TL; ডিআর
একটি গুচ্ছ পাঁচটি এনপিএম প্যাকেজদুটি ভিন্ন অ্যাকাউন্ট হ্যান্ডেলে প্রকাশিত একটি পাঠানো হয়েছে postinstall একটি হুক যা হোস্ট থেকে ক্লাউড ক্রেডেনশিয়াল পড়ে এবং সেগুলোকে অফ-বক্স পাঠিয়ে দেয়। প্যাকেজগুলোর নাম হয় ভুতুড়ে ও পাইরেট ধরনের — coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit এবং তারা যা কিছু সংগ্রহ করে তা একটি নকলে ক্রমিক নম্বর দেয় ecto_module: প্রেরণ করার আগে YAML ম্যানিফেস্ট। আমরা ক্লাস্টারটিকে ট্র্যাক করি যেমন ইকটোপ্লাজম.
পেলোডটি কেবল তখনই চলে যখন এটি একটি নির্দিষ্ট পরিবেশ শনাক্ত করে: এমন একটি হোস্ট যার নাম একটি ১২-অক্ষরের হেক্স স্ট্রিং এবং এর অধীনে একটি কার্যকরী ডিরেক্টরি /app/node_modules — একটি কন্টেইনারাইজড বিল্ড বা সিআই ওয়ার্কারের গঠন। যখন সেই গেটটি অতিক্রম করে, তখন হুকটি কোয়েরি করে। AWS ইনস্ট্যান্স মেটাডেটা পরিষেবা (IMDSv2) IAM রোল ক্রেডেনশিয়ালের জন্য, গণনা করে AWS সিক্রেটস ম্যানেজার তিনটি অঞ্চল জুড়ে, এনভায়রনমেন্ট ভেরিয়েবল ডাম্প করে, এর অধীনে থাকা ফাইলগুলি পড়ে। /appএবং ক্যাপচার-দ্য-ফ্ল্যাগ স্ট্রিংগুলির জন্য স্ক্র্যাপ করে। তারপর এটি দুটি উপায়ে ফলাফলটি পাচার করে: একটি বীকনের মাধ্যমে একটি webhook.site কালেক্টর এবং একটি র-আইপি এন্ডপয়েন্টে একটি ম্যানিফেস্ট PUT, সাথে লোকালহোস্ট-ফার্স্ট ফলব্যাকগুলির একটি তালিকা।
পরবর্তী প্যাকেজ বিবরণগুলিতে লেখা ছিল, "ভার্ডাসিও সাপ্লাই-চেইন পরীক্ষার জন্য সিটিএফ পেলোড।" আমরা এই স্ব-বিবরণটিকে একটি পর্যবেক্ষণযোগ্য ঘটনা হিসেবে উল্লেখ করছি। এর আচরণ — একটি পাবলিক আইপি-তে সরাসরি বহির্গমন, প্রকৃত আইএমডিএস ক্রেডেনশিয়াল রিড, প্রকৃত সিক্রেটস ম্যানেজার কল — লেবেল নির্বিশেষে যা তাই, এবং এই কারণেই এই সংস্করণগুলিকে ক্ষতিকারক হিসেবে শ্রেণীবদ্ধ করা হয়েছিল।
ক্লাস্টারের একটি নাম, coral-wraithএকটি মাত্র প্রকাশে থেমে থাকেনি। কয়েক ঘণ্টার মধ্যেই দ্রুতগতিতে একের পর এক কয়েক ডজন সংস্করণ পুনঃপ্রকাশ করেছিল — 1.0.0 আরোহণ করতে 6.0.0 এবং একই নামের আগের একটি পর্বে স্ফীত ব্যবহার করা হয়েছিল 9999.0.x সংস্করণ সংখ্যা, একটির ক্লাসিক আকৃতি নির্ভরতা-বিভ্রান্তি প্রচেষ্টাএই ব্যাপক পরিবর্তনের মধ্য দিয়ে পেলোডটি দৃশ্যত আরও পরিণত হয়েছে: একটি এককালীন হোস্ট-গণনা বীকন থেকে এটি একটি পূর্ণাঙ্গ AWS ক্রেডেনশিয়াল পিভটে রূপান্তরিত হয়েছে, যা এমন পরিবেশগত যাচাই প্রক্রিয়ায় আবৃত থাকে যা এটিকে এর উদ্দিষ্ট লক্ষ্যের বাইরে গোপন রাখে।
| প্যাকেজ | ৫টি নাম; coral-wraith একাই কয়েক ডজন সংস্করণে পুনঃপ্রকাশিত |
| ইকোসিস্টেম | npm |
| ভেক্টর ইনস্টল করুন | postinstall জীবনচক্র স্ক্রিপ্ট |
| প্রাথমিক লক্ষ্য | AWS IAM রোলের ক্রেডেনশিয়াল + সিক্রেটস ম্যানেজারের গোপনীয় মান, এনভায়রনমেন্ট ভেরিয়েবল, /app নথি পত্র |
| এক্সফিল | webhook.site বীকন + কাঁচা-আইপি সি২ পুট |
| ট্রিগার গেট | ১২-হেক্স হোস্টনেম + /app/node_modules বর্তমান ডিরেক্টরি (cwd), এবং এর সাথে একটি পরিবেশগত যাচাই যা সেই প্রেক্ষাপটের বাইরে পেলোডকে দমন করে। |
| নির্দয়তা | উচ্চ — ক্লাউড ক্রেডেনশিয়াল এবং পরিচালিত-গোপনীয় তথ্য প্রকাশ কন্টেইনারাইজড বিল্ড এবং রানটাইম পরিবেশ |
শারীরস্থান আক্রমণ করুন
ক্লাস্টারের প্রতিটি প্যাকেজ একই উপায়ে তৈরি করা হয়: একটি প্রায়-খালি index.js (মডিউল.এক্সপোর্টস = {}), এক লাইনের package.json স্ক্রিপ্ট — “পোস্টইনস্টল”: “নোড পোস্টইনস্টল.জেএস” এবং পেলোড পোস্টইনস্টল.জেএসহুকটি চালানোর জন্য প্যাকেজটি ইনস্টল করাই যথেষ্ট; কোনো ইম্পোর্ট বা কল করার প্রয়োজন নেই।
টার্গেটিং গেট। কোনো কিছু করার আগে, এক্টো-ফ্যামিলি পেলোডটি তার চারপাশ পরীক্ষা করে নেয়:
function isAppWorker(): host = os.hostname() if host does NOT match /^[0-9a-f]{12}$/ -> exit if cwd does NOT contain "/app/node_modules" -> exit if cwd contains "/tmp/npm-safe" -> exit otherwise -> proceed ডকার একটি কন্টেইনারকে ডিফল্টভাবে যে আকারের হোস্টনেম বরাদ্দ করে, তা হলো একটি ১২-হেক্স হোস্টনেম, এবং /অ্যাপ/নোড_মডিউল এটি একটি প্রচলিত ইন-কন্টেইনার ইনস্টল পাথ। যদি পাথটি একটি স্যান্ডবক্সড এক্সট্র্যাকশন ডিরেক্টরির মতো দেখায়, তবে তৃতীয় ক্লজটি বাতিল হয়ে যায়। এর ফলে পেলোডটি একজন ডেভেলপারের ল্যাপটপ বা অ্যানালাইসিস স্যান্ডবক্সে নিষ্ক্রিয় অবস্থায় থাকে এবং শুধুমাত্র একটি কন্টেইনারাইজড বিল্ড বা রানটাইম ওয়ার্কারের ভিতরে সক্রিয় হয় — এই ধরনের পরিবেশেই লাইভ ক্লাউড ক্রেডেনশিয়াল থাকার সম্ভাবনা সবচেয়ে বেশি। ক্লাস্টারের সবচেয়ে পুরনো প্যাকেজ, প্রবাল-প্রেতএর এমন কোনো গেট নেই এবং এটি তার (সরলতর) সংগ্রহটি শর্তহীনভাবে চালায়।
সংগ্রহযখন গেটটি পার হয়ে যায়, তখন হুকটি খোলসের মধ্য দিয়ে বেরিয়ে আসে। execFileSync(“/bin/sh”, [“-c”, …]) এবং ক্রমানুসারে নিম্নলিখিত একক যৌগিক কমান্ডগুলো চালায়:
1. PUT /latest/api/token to 169.254.169.254 (IMDSv2 token request) 2. GET .../iam/security-credentials/ (IAM role name) 3. GET .../iam/security-credentials/<role> (temporary credentials) 4. dump env | sort (environment variables) 5. list /app (excl. node_modules) + cat first 15 (application files) 6. aws secretsmanager list-secrets (us-east-1, eu-west-1, eu-central-1) 7. scrape readable files for HTB{...} (capture-the-flag strings) ধাপ ১-৩ হলো IMDSv2 পুনরুদ্ধারের একটি আদর্শ পদ্ধতি: একটি সেশন টোকেনের জন্য অনুরোধ করুন, তারপর সেটিকে সংযুক্ত করুন। X-aws-ec2-metadata-token ইনস্ট্যান্সের IAM রোল এবং সেই রোলের অস্থায়ী অ্যাক্সেস কীগুলো পাওয়ার জন্য হেডার। সহজতর প্রমাণীকরণবিহীন IMDSv1-এর পরিবর্তে IMDSv2 বাস্তবায়নের সিদ্ধান্ত। পাওয়া এটি লক্ষণীয় যে — এর মানে হলো, পেলোডটি সেইসব ইনস্ট্যান্সেও কাজ করে যেগুলোকে টোকেন-ভিত্তিক মেটাডেটা অ্যাক্সেসের জন্য কনফিগার করা হয়েছে, যা AWS-এর প্রস্তাবিত সুরক্ষা ব্যবস্থা। ধাপ ৩ দ্বারা ফেরত আসা ক্রেডেনশিয়ালগুলো স্বল্পস্থায়ী। অ্যাক্সেস কী আইডি/গোপন অ্যাক্সেস কী/টোকেন ট্রিপলগুলো ইনস্ট্যান্সের রোলের আওতাভুক্ত; সেই রোল যা যা করতে পারে, সেই কীগুলোর ধারক ক্রেডেনশিয়ালটির জীবনকাল জুড়ে তা-ই করতে পারবে।
ধাপ ৪-৬ টেকটিকে প্রশস্ত করে। প্রায় ডাম্প বিল্ড বা রানটাইম প্রসেস দ্বারা প্রাপ্ত সবকিছু ধারণ করে — বাস্তবে, রেজিস্ট্রি টোকেন, ডাটাবেস কানেকশন স্ট্রিং এবং এপিআই কী-গুলো বেশিরভাগ ক্ষেত্রেই এখানেই থাকে। / অ্যাপ ফাইল ওয়াক বাইরে থেকে পনেরোটি পর্যন্ত অ্যাপ্লিকেশন ফাইল পড়ে। নোড_মডিউলস, যা পৃষ্ঠতল বিন্যাস হতে পারে, .env ফাইল, বা উৎস। ধাপ ৬ কল করে AWS SecretsManager List-Secrets তিনটি অঞ্চলে; ধাপ ১-৩ এ প্রাপ্ত ক্রেডেনশিয়ালগুলোই ঐ কলগুলোকে প্রমাণীকরণ করে, তাই IMDS রিড এবং সিক্রেটস ম্যানেজার এনুমারেশন চেইন একত্রিত হয়ে একটি একক এসকেলেশন তৈরি করে: ইনস্ট্যান্স রোল → ম্যানেজড-সিক্রেট ইনভেন্টরি। ধাপ ৭ হলো ক্যাপচার-দ্য-ফ্ল্যাগ কাঠামোর প্রতি একটি ইঙ্গিত — যখন একটি এইচটিবি{…} ফ্ল্যাগটি পাওয়া গেলে তা আলাদাভাবে পাঠানো হয়, অন্যথায় সংগৃহীত মূল ডেটাখণ্ডটিকে চারটি খণ্ডে বিভক্ত করে পাঠানো হয়।
ক্লাস্টারের পরবর্তী সংস্করণগুলো এই প্রক্রিয়াকে আরও এগিয়ে নিয়ে যায়। শুধু ইনভেন্টরি করেই থেমে না গিয়ে, তারা IMDS রেসপন্সটি পার্স করে এবং টেম্পোরারি কী-গুলো এক্সপোর্ট করে। AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN পরিবেশ ভেরিয়েবল দিয়ে পরিচয় নিশ্চিত করুন aws sts get-caller-identityএবং তারপরে এর দ্বারা ফেরত আসা প্রতিটি গোপনীয় তথ্যের উপর লুপ চালান। তালিকা-গোপনীয় কলিং aws secretsmanager get-secret-value প্রতিটিতে — শুধু তাদের নাম নয়, গোপন বিষয়বস্তুও পুনরুদ্ধার করা হয়। একই সংস্করণগুলি প্রসেস-প্রতিস্থাপিত ফ্ল্যাগ বাইনারিগুলিও পড়তে পারে (/পড়ুনপতাকা এবং বন্ধুরা) এবং একটি চেষ্টা করুন কার্গো রান যেকোনো রাস্ট প্রকল্পের বিরুদ্ধে যা পাওয়া গেছে / অ্যাপক্লাউড ক্রেডেনশিয়ালের বাইরে গিয়ে বিল্ড এনভায়রনমেন্ট যা কিছু প্রকাশ করে, তার সবকিছু অন্তর্ভুক্ত করে আহরণের পরিধি প্রসারিত করা।
এই পরবর্তী সংস্করণগুলো আরও কঠোরভাবে নিজেদেরকে গেট করে। ১২-হেক্স-হোস্টনেম এবং এর পাশাপাশি /অ্যাপ/নোড_মডিউল চেক করার সময়, পেলোডটি সক্রিয় প্যাকেজ-রেজিস্ট্রি কনফিগারেশন এবং ওয়ার্কিং-ডিরেক্টরি পাথ পরীক্ষা করে এবং যখন এগুলি কোনো লাইভ টার্গেটের পরিবর্তে একটি অ্যানালাইসিস বা মিরর কনটেক্সট নির্দেশ করে, তখন এটি নীরবে এক্সিট করে। এর সম্মিলিত ফল হলো এমন একটি পেলোড যা বেশিরভাগ ইন্সপেকশন এনভায়রনমেন্টে দৃশ্যমান কিছুই করে না এবং শুধুমাত্র সেখানেই তার সম্পূর্ণ ডেটা সংগ্রহ চালায়, যেখানে এটি নিজেকে একটি প্রকৃত কন্টেইনারাইজড হোস্ট হিসেবে শনাক্ত করে।
বহিষ্কারসংগৃহীত ডেটা দুটি চ্যানেলের মাধ্যমে হোস্ট থেকে বেরিয়ে যায়। প্রথমত, একটি বীকন পোস্ট একটি নির্দিষ্ট webhook.site কালেক্টর, যা হোস্টনেম, নিউমেরিক ইউআইডি, ওয়ার্কিং ডিরেক্টরি এবং ১২০ কেবি পর্যন্ত সংগৃহীত ডেটা বহন করে। দ্বিতীয়ত, ডেটা একটি নকল YAML “মডিউল ম্যানিফেস্ট”-এর মধ্যে ভাঁজ করা হয় এবং PUT থেকে /api/modules/ একটি টার্গেট সার্ভারে:
ecto_module: name: "<flag-or-chunk-0>" version: "1.0.0" power_level: "<chunk-1>" ship_deck: "<chunk-2>" cargo_hold: "<chunk-3>" ম্যানিফেস্ট ফিল্ডের নামগুলি (পাওয়ার_লেভেল, জাহাজের ডেক, কার্গো_হোল্ডএগুলো হলো সজ্জা — চুরি করা ডেটা স্ট্রিং ভ্যালুগুলোর ভেতরে থাকে, যে কারণে একটি নেটওয়ার্ক মনিটর এটিকে একটি সুস্পষ্ট ডেটা ডাম্পের পরিবর্তে একটি নিরীহ প্যাকেজ-রেজিস্ট্রি ম্যানিফেস্ট আপলোডের মতো দেখে। বীকন চ্যানেলটি আরও অনেক কিছু বহন করে: পোস্ট শরীর webhook.site এর মধ্যে হোস্টনেম, নিউমেরিক ইউআইডি, ওয়ার্কিং ডিরেক্টরি এবং সংগৃহীত ব্লবের ১২০ কেবি পর্যন্ত অংশ অন্তর্ভুক্ত থাকে, তাই একটিমাত্র সফল বীকনও সম্পূর্ণ ডেটা সরবরাহ করে। webhook.site এটি একটি বিনামূল্যের অনুরোধ-পরিদর্শন পরিষেবা; এটিকে সংগ্রাহক হিসেবে ব্যবহার করার অর্থ হলো, অপারেটরকে সেই চ্যানেলের জন্য নিজস্ব কোনো গ্রহণকারী পরিকাঠামো তৈরি করতে হয় না এবং রেকর্ড করা অনুরোধগুলো পরিষেবাটির বিনে সংরক্ষিত থাকে।
ম্যানিফেস্ট PUT একটি বিকল্প তালিকা ধরে এগোয় যা কয়েকটি দিয়ে শুরু হয় 127.0.0.1/স্থানীয় হোস্ট বন্দরগুলো এবং তারপর `-এর তিনটি পাবলিক অ্যাড্রেসে চলে যায়।১৫৪.৫৭.১৬৪.০/২৪` এই প্রক্রিয়াটি একটি রেঞ্জের মধ্যে ঘটে এবং প্রথম যে এন্ডপয়েন্টটি 2xx স্ট্যাটাস দিয়ে উত্তর দেয়, সেখানেই থেমে যায়। লোকালহোস্ট-প্রথম এই ক্রমটি “ভার্ডাসিও টেস্টিং” নামক স্ব-বর্ণনার (লুপব্যাকে থাকা একটি লোকাল রেজিস্ট্রি) সাথে সামঞ্জস্যপূর্ণ, কিন্তু পাবলিক-আইপি ফলব্যাকের অর্থ হলো, যখনই লুপব্যাক লিসেনিং অবস্থায় থাকে না, তখনই ডেটা হোস্ট ছেড়ে চলে যায় — অর্থাৎ, লেখকের নিজের টেস্ট রিগ ছাড়া অন্য যেকোনো মেশিনে এটি ঘটে।
Timeline
ক্লাস্টারটি এককালীন পতনের পরিবর্তে ক্রমবর্ধমান সক্ষমতা বৃদ্ধি প্রদর্শন করে। আমরা এটিকে পর্যবেক্ষণকৃত আচরণের ভিত্তিতে সাজাই, প্রকাশের নির্দিষ্ট সময়সীমার ভিত্তিতে নয়:
| পর্যায় | প্যাকেজ / সংস্করণ | আচরণ |
|---|---|---|
| প্রাথমিক দৌড় | coral-wraith 9999.0.x | নির্ভরতা-বিভ্রান্তি প্রচেষ্টার সাথে সামঞ্জস্যপূর্ণ স্ফীত সংস্করণ নম্বর; ইনস্টল-সময়ের গণনা এবং এক্সফিল |
| বীজ | coral-wraith 1.0.0 | পোস্টইনস্টল id/env/flag ফাইল সংগ্রহ করে; একক PUT-এর মাধ্যমে 154[.]57[.]164[.]71:30782, চিহ্নিতকারী ECT-472839 |
| দ্রুত পুনরাবৃত্তি | coral-wraith 1.0.1 → 6.0.0 | কয়েক ঘণ্টার মধ্যে কয়েক ডজন নিক্ষেপ; পেলোডটি লাভ করে isAppWorker() গেট, IMDSv2 ক্রেডেনশিয়াল পুল, সম্পূর্ণ get-secret-value পিভট, রেজিস্ট্রি/পাথ এনভায়রনমেন্ট চেক, এবং ডুয়াল সিঙ্ক মার্কার |
| সমান্তরাল নাম | ecto-corsair-whisper-6f3b9 1.0.14–1.0.18 | একই গেটেড পেলোড; webhook.site বীকন এবং মাল্টি-এন্ডপয়েন্ট ফলব্যাক তালিকা |
| রুপভেদ | ecto-rust-read-f3a9c1 1.0.1–1.0.2 | অতিরিক্ত সিঙ্ক মার্কার যোগ করে ECT-987654, ECT-654321, ECT-839201 |
| রুপভেদ | ecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0 | একই গেটেড পেলোড, একই সি২ এবং বীকন |
এই ক্লাস্টারের প্রধান বৈশিষ্ট্য হলো এর প্রকাশের ধরণ: একটি প্যাকেজ ও একটি সংস্করণের পরিবর্তে, একই নাম দ্রুত পরপর বারবার পুনঃপ্রকাশ করা হয়, প্রতিটি রিলিজ পূর্ববর্তীটির একটি সামান্য পরিবর্তিত রূপ, এবং এর পাশাপাশি একই পেলোড বহনকারী ভিন্ন নামের আরও কয়েকটি সংস্করণ থাকে। ফিস্ ফিস্ শব্দ কোডটি দুটি কাছাকাছি ফিঙ্গারপ্রিন্টে বিভক্ত হয়েছে — একটি সেট দুটি গুরুতর ডিটেকশন ট্রিগার করে, অন্যটি তিনটি (একটি অতিরিক্ত ফাইল-রিড সিঙ্ক) — কিন্তু উভয়ই একই পেলোডে রেজলভ হয়; পার্থক্যটি হলো কোড ড্রিফট, কোনো বিহেভিওরাল ফর্ক নয়। ফিস্ ফিস্ শব্দ বিশ্লেষিত পরিসরের বাইরে (এই লেখাটি লেখার সময় অন্তত ১.০.২৫ পর্যন্ত) রেজিস্ট্রি-তে সরাসরি পর্যবেক্ষণ করা হয়েছিল, এবং প্রবাল-প্রেত নামটি একই জানালার ওপর দিয়ে তার নিজস্ব সংস্করণের মই বেয়ে উঠতে থাকল।
সমঝোতার সূচক
নীচের সমস্ত সূচক ডিস্কে থাকা প্যাকেজ উৎস থেকে সংগ্রহ করা হয়েছে। নেটওয়ার্ক সূচকগুলোর কার্যকারিতা নিষ্ক্রিয় করা হয়েছে।
নেটওয়ার্ক
| ইনডিকেটর | ভূমিকা |
|---|---|
hxxp://154[.]57[.]164[.]71:30782 | C2 PUT লক্ষ্য (coral-wraith) |
hxxp://154[.]57[.]164[.]80:30543 | C2 PUT ফলব্যাক (ecto-*) |
hxxp://154[.]57[.]164[.]82:31250 | C2 PUT ফলব্যাক (ecto-*) |
hxxp://154[.]57[.]164[.]71:31289 | C2 PUT ফলব্যাক (ecto-*) |
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5 | বীকন সংগ্রাহক |
169[.]254[.]169[.]254/latest/... | IMDSv2 ক্রেডেনশিয়াল রিড (টার্গেট-সাইড, AWS মেটাডেটা) |
আচরণগত/ফাইল
| ইনডিকেটর | ভূমিকা |
|---|---|
"postinstall": "node postinstall.js" | ভেক্টর ইনস্টল করুন |
ecto_module: YAML সহ power_level / ship_deck / cargo_hold কী | এক্সফিল ম্যানিফেস্ট স্কিমা |
সিঙ্ক মার্কার ECT-472839, ECT-987654, ECT-654321, ECT-839201 | C2 পথের অংশ /api/modules/<marker> |
isAppWorker() গেট: হোস্ট /^[0-9a-f]{12}$/, cwd-তে রয়েছে /app/node_modules | সক্রিয়করণ শর্ত |
aws secretsmanager list-secrets শেষ us-east-1, eu-west-1, eu-central-1 | গোপনীয়তা গণনা |
HTB{...} রেজেক্স স্ক্র্যাপ | ক্যাপচার-দ্য-ফ্ল্যাগ ফসল |
ফাইল হ্যাশ (sha256, বিশ্লেষণের সময় সংগৃহীত)
| ফাইল | sha256 |
|---|---|
coral-wraith/postinstall.js | ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824 |
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js | b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3 |
আরোপণ এবং পর্যবেক্ষণকৃত আচরণ
পাঁচটি প্যাকেজের নাম দুটি এনপিএম অ্যাকাউন্ট হ্যান্ডেলের অধীনে প্রকাশিত হয়েছিল, কিন্তু সেগুলোকে একটি ক্লাস্টার হিসেবে গণ্য করার জন্য তাদের মধ্যে যথেষ্ট অবকাঠামোগত মিল রয়েছে: একই এক্টো_মডিউল ম্যানিফেস্ট স্কিমা, একই ইসিটি-০৪৫ প্রাথমিক সিঙ্ক চিহ্নিতকারী, একই webhook.site কালেক্টর আইডি, এবং একই C2 এন্ডপয়েন্ট `154.57.164.0/24` ব্লক। সীড প্যাকেজ (`coral-wraith`), সরলতর এবং আনগেটেড) এবং গেটেড এক্টো-ফ্যামিলিকে তাই স্বাধীন প্রচেষ্টার পরিবর্তে একটি টুলকিটের পুনরাবৃত্তি হিসাবে পড়া হয়।
পরবর্তী সংস্করণগুলিতে প্যাকেজগুলি নিজেদেরকে এভাবে বর্ণনা করে ভার্ডাসিও সরবরাহ-শৃঙ্খল পরীক্ষার জন্য সিটিএফ পেলোড। আমরা সেই লেবেলটিকে একটি পর্যবেক্ষণযোগ্য তথ্য হিসেবে তুলে ধরি এবং উদ্দেশ্য সম্পর্কে কোনো পর্যবেক্ষণ হিসেবে এটিকে পুনরায় উল্লেখ করি না। কোডটি যা করে তা দ্ব্যর্থহীন এবং এটিকে কীভাবে লেবেল করা হয়েছে তার উপর নির্ভরশীল নয়: এটি ইনস্ট্যান্স মেটাডেটা সার্ভিস থেকে IAM রোলের ক্রেডেনশিয়াল পড়ে, তিনটি AWS রিজিয়ন জুড়ে ম্যানেজড সিক্রেটগুলো গণনা করে, এবং ফলাফলগুলো একটি পাবলিক আইপি ও একটি থার্ড-পার্টি ওয়েবহুক কালেক্টরের কাছে প্রেরণ করে। একটি সত্যিকারের লুপব্যাক-অনলি টেস্ট হারনেসের পাবলিক-আইপি ফলব্যাক লিস্ট, IMDS ক্রেডেনশিয়াল রিড, বা ক্রস-রিজিয়ন সিক্রেটস ম্যানেজার কলের প্রয়োজন হবে না। যেহেতু ইগ্রেস এবং ক্রেডেনশিয়াল রিচ বাস্তব, তাই গেটেড সংস্করণগুলোকে ক্ষতিকর হিসেবে শ্রেণীবদ্ধ করা হয়েছিল।
শুধুমাত্র কন্টেইনারের জন্য নির্দিষ্ট গেটটিই হলো কার্যকারিতার দিক থেকে সবচেয়ে উল্লেখযোগ্য বৈশিষ্ট্য। এটি একই সাথে একটি এড়ানোর কৌশল—ল্যাপটপ এবং অ্যানালাইসিস স্যান্ডবক্সে নীরব থাকা—এবং একটি লক্ষ্য নির্ধারণের কৌশল, যা কেবল সেখানেই সক্রিয় হয় যেখানে একটি প্রকৃত IAM রোল এবং লাইভ সিক্রেটস থাকার সম্ভাবনা সবচেয়ে বেশি। কোনো সাধারণ স্যান্ডবক্সে এই প্যাকেজগুলো চালানো বিশ্লেষকরা কিছুই লক্ষ্য করবেন না; এই আচরণটি কেবল একটি ডকার-ধাঁচের হোস্টনেম এবং কন্টেইনারের ভেতরের ইনস্টল পাথের অধীনেই প্রকাশ পায়।
প্রতিরক্ষাকারীদের জন্য প্রভাব, প্রবণতা ও নির্দেশনা
এখানে ঝুঁকিটি হলো বিল্ড এবং রানটাইম কন্টেইনারের অভ্যন্তরে ক্লাউড-ক্রেডেনশিয়াল এবং গোপনীয় তথ্য ফাঁস হয়ে যাওয়া। IMDS থেকে প্রাপ্ত একটি IAM রোল ক্রেডেনশিয়াল সেই রোলের সমস্ত অনুমতি বহন করে; গোপনীয়তা ব্যবস্থাপক: গোপনীয়তা তালিকা (এবং যেকোনো পরবর্তী GetSecretValueএর পরিধি প্রসারিত হয়ে সংরক্ষিত অ্যাপ্লিকেশন সিক্রেট পর্যন্ত বিস্তৃত হয়। এনভায়রনমেন্ট-ভেরিয়েবল ডাম্পে প্রায়শই রেজিস্ট্রি টোকেন, ডাটাবেস ইউআরএল এবং এপিআই কী থাকে। একটি সিআই বা কন্টেইনার প্রেক্ষাপটে—ঠিক যেটির জন্যই গেটটি নির্বাচন করে—এই প্যাকেজগুলোর যেকোনো একটির একটিমাত্র ট্রানজিটিভ ইনস্টলই সেই উপাদান ফাঁস করার জন্য যথেষ্ট।
এক্টোপ্লাজম এমন একটি প্যাটার্নের সাথে মিলে যায় যা আমরা ক্রমাগত দেখতে পাচ্ছি: ইনস্টল-টাইম পেলোড যা স্থানীয় ফাইলের পরিবর্তে ক্লাউড মেটাডেটা এবং পরিচালিত গোপনীয় তথ্য ব্যবহার করে, এবং যা শুধুমাত্র উচ্চ-মূল্যের পরিবেশে সক্রিয় হওয়ার জন্য নিজেকে গেট করে রাখে। এর বিরুদ্ধে দুটি প্রতিরক্ষামূলক পর্যবেক্ষণ নিচে দেওয়া হলো।
- আকৃতিটি শনাক্তযোগ্যএকটি npm/PyPI ইনস্টল হুক যার কল গ্রাফ একটি ক্লাউড সিক্রেটস এপিআই উভয়কেই স্পর্শ করে (AWS সিক্রেটস ম্যানেজার, জিক্লাউড গোপনীয়তা, আজ কীভল্ট) অথবা IMDS অ্যাড্রেস এবং একটি নেটওয়ার্ক ইগ্রেস সিঙ্ক হলো একটি সংকীর্ণ, উচ্চ-সংকেত প্যাটার্ন — এটি একটি বৈধ লাইফসাইকেল স্ক্রিপ্টে প্রায় কখনোই ঘটে না। স্থির প্রবাহ বিশ্লেষণ কোনো নির্দিষ্ট ডোমেইন বা আইপি-র ওপর নির্ভর না করেই এটিকে চিহ্নিত করা যায়।
- পরিবেশগত দৃঢ়তা একে ভোঁতা করে দেয়। ১-এর হপ লিমিট সহ IMDSv2 প্রয়োগ করা হলে কন্টেইনার ওয়ার্কলোডগুলো ইনস্ট্যান্স মেটাডেটাতে পৌঁছাতে পারে না; IAM রোলগুলোকে সর্বনিম্ন বিশেষাধিকার পর্যন্ত সীমাবদ্ধ রাখলে ফাঁস হওয়া যেকোনো ক্রেডেনশিয়ালের প্রভাব সীমিত থাকে; এবং ইনস্টলগুলো চালানো হয়... স্ক্রিপ্টগুলি উপেক্ষা করুন CI-তে যেসব প্যাকেজের প্রয়োজন নেই, তাদের জন্য install-hook ভেক্টরটি সম্পূর্ণরূপে সরিয়ে দেওয়া হয়।
ডিফেন্ডারদের জন্য কার্যকরী পরীক্ষাগুলো হলো: বিল্ড/সিআই কন্টেইনার থেকে অনুমোদিত নয় এমন পাবলিক আইপি-তে বহির্গামী সংযোগের ক্ষেত্রে অ্যালার্ট দেওয়া। npm ইনস্টল করুনপ্যাকেজ লাইফসাইকেল স্ক্রিপ্ট থেকে উদ্ভূত IMDS অ্যাক্সেসের বিষয়ে সতর্ক থাকুন; এবং অন্যথা প্রমাণিত না হওয়া পর্যন্ত, ক্লাউড CLI-তে শেল আউটপুট করে এমন যেকোনো ইনস্টল হুককে সন্দেহজনক হিসেবে বিবেচনা করুন।
এই ক্লাস্টারের জন্য নির্দিষ্ট আরও দুটি বিষয় লক্ষণীয়। প্রথমত, যেহেতু অ্যাক্টিভেশন শুধুমাত্র কন্টেইনারাইজড এনভায়রনমেন্টের জন্য সীমাবদ্ধ, তাই একটি প্যাকেজ যা ওয়ার্কস্টেশনে যাচাই করার সময় নিষ্ক্রিয় বলে মনে হয়, সেটি প্রোডাকশনে লাইভ থাকতে পারে — যাচাই করার জন্য কন্টেইনারের হোস্টনেম এবং পাথের শর্তগুলো পুনরায় তৈরি করতে হবে, অথবা সরাসরি সোর্স কোড পড়তে হবে, শুধু “আমি এটি ইনস্টল করেছি এবং কিছুই হয়নি” এই যুক্তির উপর নির্ভর করলে চলবে না। দ্বিতীয়ত, বীকন কালেক্টর হিসেবে একটি পাবলিক রিকোয়েস্ট-ইন্সপেকশন সার্ভিস ব্যবহারের অর্থ হলো, পাচার হওয়া কিছু ডেটা ইনসিডেন্ট রেসপন্সের জন্য পুনরুদ্ধারযোগ্য হতে পারে: কোনো সংস্থা যদি তার ডিপেন্ডেন্সি ট্রিতে এই প্যাকেজগুলোর একটি খুঁজে পায়, তবে তারা পেলোডের কালেকশন লজিক থেকে একটি সফল বীকনে কী কী থাকতে পারত সে সম্পর্কে ধারণা করতে পারবে, এবং প্রভাবিত বিল্ড বা রানটাইম এনভায়রনমেন্ট থেকে অ্যাক্সেসযোগ্য যেকোনো IAM রোল ক্রেডেনশিয়াল, রেজিস্ট্রি টোকেন এবং ম্যানেজড সিক্রেট পরিবর্তন করে ফেলা উচিত। শংসাপত্র ঘূর্ণনএকবার ইনস্টলেশন সম্পন্ন হয়ে গেলে, প্যাকেজ অপসারণ নয়, বরং সেটিই হলো কার্যকর প্রতিকার।





