Sadržaj

Malware u PyPI ekosustavu

Videoprezentacija

Sažetak

PyPI, centralni repozitorij za Python pakete, ključan je za ubrzani razvoj softvera, ali njegova otvorenost čini ga ranjivim na maliciozne pakete. Napadači koriste različite metode za distribuciju zlonamjernog koda, poput manipulacije verzijama ovisnosti, imitacije popularnih biblioteka (typosquatting) ili implementacije skrivene maliciozne funkcionalnosti. Primjeri poput incidenta s PyTorchom i lažnih paketa poput “nupmy” pokazuju ozbiljnost prijetnje.

Uvod

Python je danas jedan od najpopularnijih programskih jezika. Jedan od razloga za to je bogat ekosustav biblioteka koje značajno ubrzavaju razvoj aplikacija. Često kada programiramo u Pythonu, već postoji biblioteka koja rješava neke od naših problema, tako da ne moramo iz nule implementirati. Također, popularne biblioteke su obično dobro testirane i pouzdane, pružajući vjerojatno veću kvalitetu i učinkovitost od vlastite implementacije.

Centralno mjesto za distribuciju, PyPI (Python Package Index) je repozitorij gdje programeri objavljuju biblioteke, radne okvire i alate koje onda drugi korisnici mogu integrirati u svoje projekte kako bi si ubrzali i olakšali razvoj softvera.

Neki od najpoznatijih paketa su numpy i pandas. Ti alati su postali standard do te razine da je razvoj umjetne inteligencije postao nezamisliv bez numpy-a. Međutim, ove biblioteke su samo obični programi napisani od strane neke druge osobe ili tima. Rijetko kad nas zanima sama implementacija njihovih funkcija, već ih uglavnom koristimo kao crne kutije. No, što ako, recimo, netko od razvijatelja numpy biblioteke postane zao, i ubaci maliciozan kod koji će tražiti lozinke po našem računalu te ih slati na udaljeni poslužitelj?

Nažalost, upravo zbog otvorene prirode PyPI-a, gdje svatko može objaviti paket, takav scenarij nije isključen. Dalje u radu ću objasniti kako se paketi objavljuju na PyPI, prikazati primjere što sve maliciozan kod u paketu može napraviti i njihovih tehnika prikrivanja te predstaviti metode za detekciju takvih sigurnosnih prijetnji.

Kako funkcioniraju PyPI paketi, kako se objavljuju

U svojoj srži, PyPI paketi su arhive, uglavnom .tar.gz ili .whl, koje možemo shvatiti slično kao .zip arhive. One u sebi sadrže Python kod, metapodatke te druge resurse potrebne za distribuciju. Kada korisnik želi instalirati neki paket, poziva naredbu “pip install ime_paketa” iz komandne linije. Ovo dohvati paket iz PyPI repozitorija, zajedno s paketima o kojima ovisi, te ih onda instalira u korisnikovo Python okruženje. Nakon toga, paket je spreman za upotrebu i može se jednostavno integrirati u program pomoću naredbe “import ime_paketa”.

Za kreiranje paketa, ukratko, potrebno je imati određenu strukturu direktorija gdje se nalazi kod koji želimo pretvoriti u paket (Slika 1). Primjer potrebne datoteke je pyproject.toml, koja specificira stvari poput imena i opisa paketa, verzije, ovisnosti te ulaznih točaka. Kada se ostvari poželjna struktura, pozivom naredbe “python -m build” se kreira “dist/” direktorij u kojem se nalaze arhive paketa.

pypi_package_structure.jpg

Slika 1. Struktura direktorija Python paketa

Više o kreiranju paketa možete pronaći ovdje.

Za objavljivanje paketa na PyPI, potrebno je napraviti korisnički račun na PyPI te preuzeti API token za autentifikaciju. Za sami upload, preporuča se koristiti alat twine iz komandne linije kojem predajemo putanju do arhiva paketa te API ključ. Nakon uspješne objave, paket postaje dostupan drugim korisnicima putem PyPI repozitorija.

Primjer malicioznog paketa

Kako bismo bolje razumjeli što maliciozni PyPI paketi mogu učiniti, osvrnut ćemo se na jedan nedavno otkriveni primjer.

U srpnju 2024. FortiGuard Labs je otkrio PyPI paket koji je pri svojoj inicijalizaciji preuzimao datoteke sa malicioznog URL-a (Slika 2), jedna od kojih je bila izvršna datoteka koja se automatski pokušavala pokrenuti. Forenzičkom analizom otkriveno je da je izvršna datoteka zapakirana koristeći PyInstaller te su reverznim inženjerstvom došli do izvornog koda programa.

Slika 2. Preuzimanje datoteka pri inicijalizaciji paketa

U izvornom kodu su se nalazile tri sumnjive datoteke: “Discord_token_grabber.py”, “get_cookies.py” i “password_grabber.py”. Cilj svakog programa je bio ukrasti određene osjetljive informacije s korisnikovog računala te ih poslati na udaljeni poslužitelj. Primjerice, “Discord_token_grabber.py” je po “AppData” direktoriju na Windowsima tražio korisnikov Discord token koji se može koristiti za autentikaciju. Koristili su regularne izraze kako bi našli potencijalne tokene, a zatim bi sa svakim tokenom pokušali napraviti zahtjev na Discord API te vidjeli hoće li poslužitelj vratiti status 200. Ako hoće, pokušati će preko Discord API-ja dohvatiti korisnikove spremljene načine plaćanja te neke druge informacije o korisniku (Slika 3).

Slika 3. Dohvaćanje osjetljivih informacija preko Discord API-ja

Dohvaćene informacije se zatim šalju na maliciozni poslužitelj koji ih sprema. “Get_cookies.py” i “password_grabber.py” su se fokusirali na krađu kolačića i spremljenih lozinki iz lokalnih preglednika.

Ovaj primjer ističe jedan od najočitijih oblika malicioznih aktivnosti – izvršavanje zlonamjernog koda odmah pri inicijalizaciji paketa. Međutim, ovo nije jedini način na koji maliciozni paketi mogu djelovati.

Zlonamjerni paket može, primjerice, diskretno presretati podatke. Zamislimo biblioteku koja olakšava rad s bazama podataka – maliciozna verzija takvog paketa mogla bi slati unesene podatke na napadačev poslužitelj prije nego što ih pohrani u vašu bazu. Ovakve manipulacije otvaraju širok spektar mogućnosti za napadače, a granice ovise samo o njihovoj domišljatosti.

Više o ovom paketu možete pronaći ovdje.

Primjeri prikrivanja malicioznih paketa

Maliciozni paketi često koriste kreativne tehnike kako bi ostali neprimijećeni i proširili se na što veći broj korisnika. Evo nekoliko primjera takvih strategija:

Manipulacijama verzijama ovisnosti

U prosincu 2022., PyTorch, popularan radni okvir za strojno učenje, je objavio da je u sebi imao uključenu malicioznu ovisnost. Način na koji se maliciozni paket uvukao u ovisnosti je tako što je zbunio PyPI jer je paket imao isto ime kao i interni, neobjavljeni, paket koji je PyTorch koristio. Naime, kod instaliranja paketa, prioritizirati će se onaj s većom verzijom. Napadači su to znali, te su javno objavili njihov maliciozni paket i stavili mu jako visoku verziju. Ovaj zlonamjerni paket ostao je neprimijećen pet dana.

Imitacija legitimnih paketa

Jedna od najčešćih taktika je stvaranje paketa s imenom koje nalikuje nekom popularnom i legitimnom paketu. Primjerice, napadač može paket umjesto “numpy” nazvati “nupmy”. Za očekivati je da će, pošto legitiman paket ima velik broj instalacija, neki korisnik nekada krivo upisati ime paketa pri instalaciji i time preuzeti malicioznu verziju. Ova metoda oslanja se na ljudske pogreške, što je čini jednostavnom, ali učinkovitom.

Maskiranje u korisne biblioteke s malicioznim skrivenim funkcionalnostima

Maliciozni paketi mogu se predstaviti kao korisne biblioteke koje zaista obavljaju određeni zadatak, dok istovremeno izvode i zlonamjerne aktivnosti. Na primjer, napadač može kreirati biblioteku koja olakšava rad s bazama podataka, ali u pozadini presreće i šalje podatke na udaljeni poslužitelj prije nego što ih pohrani u bazu korisnika. Ovo čini paket naizgled legitimnim i teže ga je otkriti.

Ovo su samo neki od načina na koje se maliciozni paketi skrivaju i šire. Što napadač bolje razumije PyPI ekosustav i njegove slabosti, to lakše može osmisliti sofisticiranije metode za distribuciju zlonamjernog koda. Ova praksa naglašava važnost opreza prilikom instalacije paketa i redovite provjere njihovih izvora i reputacije.

Detekcija malicioznih paketa

Zbog ranjivog ekosustava, određene tvrtke specijalizirane za kibernetičku sigurnost kontinuirano skeniraju PyPI repozitorij i traže maliciozne pakete. Jedan od primjera je Security Labs, koji je razvio alat GuardDog. GuardDog analizira pakete i na temelju specifičnih značajki podiže upozorenja o mogućoj zlonamjernoj aktivnosti. Na sljedećoj slici (Slika 4) prikazan je primjer takvog upozorenja:

Slika 4. Primjer GuardDog upozorenja

Te značajke su:

Prazan opis paketa: Legitimni paketi gotovo uvijek uključuju opise kako bi pojasnili svoju svrhu, dok maliciozni često ostavljaju opis prazan.

Jedna python datoteka: Paketi koji sadrže samo jednu Python datoteku mogu biti sumnjivi jer većina legitimnih paketa ima složeniju strukturu.

Prepisivanje komandi: Ako paket prepisuje ponašanje prilikom izvršenja komande install, to može ukazivati na potencijalnu malicioznu namjeru.

Izvršavanje sustavnih komandi: Paketi koji pozivaju komande operacijskog sustava izuzetno su sumnjivi jer to omogućava pokretanje zlonamjernog koda.

No, ove značajke nisu dovoljne da bi mogli sa sigurnošću reći da je paket maliciozan, već nam samo kažu da moramo obaviti detaljniju analizu.

Koraci detaljnije analize:

1. Pregled datoteke setup.py

Detaljnija analiza bi trebala započeti tako da analiziramo “setup.py” datoteku. U njoj možemo vidjeti je li paket prepisao instalacijsku komandu te unutra umetnuo maliciozan kod, kao na slici (Slika 5):

override_install.jpg

Slika 5. Prepisivanje instalacijske komande paketa

2. Analiza izvornog koda Nakon pregleda konfiguracijskih datoteka, potrebno je proučiti izvorni kod paketa kako bi se identificirale sumnjive funkcije, hardkodirani URL-ovi, ili druge neuobičajene aktivnosti.

3. Testiranje u sandbox okruženju Preuzimanje i pokretanje paketa u izoliranom sandbox okruženju omogućuje sigurno promatranje ponašanja paketa. Ovo uključuje praćenje mrežnih aktivnosti, pokrenutih procesa i promjena na datotečnom sustavu.

4. Prijava malicioznih paketa Ako analiza potvrdi da je paket maliciozan, potrebno je obavijestiti PyPI tim. Oni će poduzeti potrebne korake kako bi uklonili paket iz repozitorija i spriječili daljnju štetu.

Ova kombinacija automatske detekcije i ručne analize ključna je za zaštitu PyPI ekosustava od zlonamjernih paketa.

Zaključak

PyPI ekosustav je ključan za moderni razvoj softvera. Njegova otvorenost omogućuje programerima jednostavno dijeljenje gotovih rješenja, što uzrokuje brži razvoj aplikacija. Međutim, ta otvorenost ga čini ranjivim na zloupotrebu.

Maliciozni paketi, bilo kroz manipulaciju verzijama, imitaciju popularnih biblioteka ili skrivene funkcionalnosti, predstavljaju ozbiljan sigurnosni rizik kojeg moramo biti svjesni. Kroz primjere smo vidjeli kako sofisticirane tehnike omogućavaju napadačima da prevare korisnike i kompromitiraju njihovu sigurnost.

Unatoč ovim rizicima, alati poput GuardDoga i sličnih sustava za detekciju malicioznih paketa pokazuju kako se PyPI zajednica može boriti protiv ovih prijetnji. Automatizirani sustavi praćeni ručnim analizama, uključujući pregled konfiguracijskih datoteka, analizu koda i testiranje u sandbox okruženju, ključni su koraci u očuvanju sigurnosti ovog ekosustava.

Za programere i korisnike PyPI-a, važno je zadržati visoku razinu opreza prilikom instalacije paketa. Provjera reputacije i izvora paketa, kao i redovito ažuriranje sigurnosnih alata, može značajno smanjiti rizik od napada. PyPI ekosustav, iako ranjiv, može ostati siguran i pouzdan uz odgovornu upotrebu, sustavnu analizu i zajednički trud zajednice.

Na kraju, razvoj sigurnosnih mehanizama unutar PyPI-a, kao i edukacija korisnika o potencijalnim prijetnjama, ključni su za dugoročno očuvanje povjerenja u ovaj vitalni alat Python zajednice.

Literatura

[1] "Python Package Index", Wikipedia

[2] "Packaging Python Projects", Python

[3] "Malicious Packages Hidden in PyPI", Fortinet

[4] "Top 8 malicious attacks recently found on PyPI", sonatype

[5] "Malicious PyPI packages targeting highly specific MacOS machines", SecurityLabs