OmniBOR
Da li ste nekada imali dodira sa nekim projektom ili sistemom sa desetinama ili stotinama hiljada fajlova? Održavanje tolikog skupa datoteka nije nimalo lako, zar ne? Postizanje zadovoljavajućeg nivoa bezbednosti i otkrivanje ranjivosti fajlova u takvom sistemu sigurno prouzrokuju glavobolje svakome ko je za te zadatke zadužen. E, tu na scenu stupa OmniBOR.
Šta je OmniBOR?
Pre definicije ovog pojma, potrebno je najpre uvesti pojam artefakta (engl. artifact). To je u OmniBOR terminologiji ime za bilo koji softverski objekat od interesa. Dakle, to može da bude neki izvorni, objektni ili izvršni fajl, deljena biblioteka, slika, itd.
OmniBOR (Universal Bill Of Receipts) predstavlja minimalističku šemu za različite alate koji primaju jedan ili više artefakata kao svoj ulaz i prave jedan ili više artefakata kao svoj izlaz.

Primer šeme za proces prevođenja je dat na sledećoj slici:
OmniBOR koncept podrazumeva da se:
-
napravi ADG (Artifact Dependency Graph), koji predstavlja graf zavisnosti rezultujućih artefakata od ulaznih artefakata,
-
ugrade jedinstvene reference na kreiran ADG u rezultujuće artefakte, koje se nazivaju OmniBOR identifikatori.
Na ovaj način se u svakom artefaktu koji je generisan radom nekog alata čuva informacija o artefaktima od kojih on zavisi (engl. dependencies). Kao što je već rečeno, taj podatak se naziva OmniBOR identifikator, a sam ADG se čuva u OmniBOR Document fajlovima.
ADG
ADG za određeni artefakt je rekurzivni usmereni aciklični graf svih ulaznih artefakata koje razni alati transformišu u taj artefakt. On uključuje sve direktne “pretke” tog artefakta kao i njihove “pretke” rekurzivno, sve do fajlova sa izvornim kodom. Na primeru prevođenja fajlova sa izvornim kodom napisanim u jeziku C, ADG se može videti na slici ispod.
U praksi, informacija o svakom artefaktu koji postoji u jednoj ADG strukturi se čuva u identifikatoru tog artefakta (engl. artifact id). Prema OmniBOR shvatanju, taj identifikator treba da poseduje tri glavne osobine:
-
kanoničnost – različiti entiteti za ekvivalentne artefakte dobijaju ekvivalentne identifikatore tih artefakata
-
jedinstvenost – neekvivalentni artefakti imaju različite identifikatore
-
nepromenljivost – artefakt ne može biti promenjen, a da se ta promena ne ogleda i u njegovom identifikatoru (ova karakteristika je ključna za otkrivanje malicioznih radnji nad nekim artefaktom)
Identifikator treba da bude na jedinstven način povezan sa artefaktom i u OmniBOR konceptu je predloženo da to bude gitoid (Git Object ID) tog artefakta, zbog toga što ispunjava navedene uslove i već ima primenu u Git-u. Git Blob nekog fajla je predstavljen kao:
gde je ${size} veličina tog fajla, a ${content} njegov sadržaj. Gitoid fajla je zapravo identifikator Git Blob objekta i dobija se kada se on propusti kroz SHA1 heš funkciju. Konkretno, u slučaju OmniBOR koncepta, može se koristiti i neka druga heš funkcija. Trenutno se u implementaciji OmniBOR-a u praksi radi sa SHA1 i SHA256 heš funkcijama.
Kao što je rečeno, ADG se čuva kao skup OmniBOR Document fajlova. Njima se modeluju relacije “roditelj-dete” koje se mogu videti u ADG strukturi. Svaki artefakt koji nije list poseduje jedan OmniBOR Document fajl koji sadrži zapise o njegovoj neposrednoj “deci” u ADG-u. Za svako “dete” postoji po jedan zapis u odgovarajućem formatu u jednoj liniji fajla. Format jednog zapisa zavisi od tipa čvora “deteta” u ADG strukturi:
-
ako je čvor “dete” list, onda njegov zapis ima format

-
ako čvor “dete” nije list, onda njegov zapis ima format

Na ovaj način, za svaki artefakt je moguće dobiti potpunu sliku o načinu njegovog nastanka, sve do samih izvornih fajlova.
Zašto OmniBOR?
Glavna prednost OmniBOR koncepta je u tome što on značajno unapređuje procese identifikacije softvera i upravljanja pronađenim ranjivostima u kodu. Iako nije jedini koncept sa takvim ciljevima, OmniBOR nudi kompletnost i efikasnost u njihovom postizanju. To se ogleda u korelaciji svakog sofverskog objekta sa kompletnim i proverljivim ADG-om, koji sadrži potpun skup informacija o tome kako je taj objekat nastao (o fajlovima od kojih zavisi, izvornim fajlovima, itd). Efikasnost se postiže činjenicom da se za evidenciju o stablima zavisnosti artefakata koristi minimalna količina informacija (svodi se na primenu heš funkcija). To je, pre svega, korisno u situacijama kada je potrebno pronaći neke poznate ranjivosti u kodu. Takođe, još jedna dobra strana ovog koncepta je i to što ADG, kao njegova glavna struktura, može da se uparuje sa poznatim manama koda, ne uzimajući u obzir dubinu na kojoj se one nalaze u stablu ili korišćen jezik.
OmniBOR kreira kompletnu, konciznu i skalabilnu ADG strukturu koja pruža lako proverljiv način za vođenje evidencije o softverskim objektima, što omogućava:
-
run-time detekciju potencijalnih ranjivosti u kodu, bez obzira na dubinu u ADG strukturi,
-
ispitivanje kako je došlo do eksploatacije nekih bezbednosnih propusta.
Takođe, OmniBOR generiše jedinstvene, nepromenljive i proverljive identifikatore softverskih objekata (OmniBOR identifikatore) i time pruža:
-
mogućnost povezivanja metapodataka sa odgovarajućim softverskim objektima,
-
preciznu identifikaciju softverskih objekata koja se može koristiti u SBOM-u u situacijama kada šeme imenovanja nisu dovoljno jasne (ukoliko, recimo, dva različita alata generišu različite SBOM-ove za isti softverski artefakt, OmniBOR nam može reći da se u oba slučaja u stvari radi o istom softverskom objektu).
OmniBOR u praksi
OmniBOR zajednica svakodnevno radi na implementiranju OmniBOR koncepta u najrazličitijim jezicima i alatima. Postoji GitHub stranica koja sadrži linkove ka repozitorijumima sa raznim OmniBOR implementacijama. Trenutno, radi se na uvođenju OmniBOR koncepta (ili je on već uveden) u sledeće jezike, alate, platforme i konstrukte:
-
LLVM infrastruktura
-
GCC alat
-
BinUtils skup alata
(za sada je podrška dostupna u GNU ld, GNU as i GNU readelf alatima) -
Python jezik
-
Java jezik
-
Go jezik
-
Rust jezik
-
.NET platforma
-
GNU Patch alat
-
Bomsh
-
…
Da bi se omogućilo generisanje OmniBOR informacija u nekom alatu, potrebno je uraditi bar jednu od sledeće dve stvari:
-
proslediti odgovarajuću opciju koja omogućava računanje OmniBOR informacija, zajedno sa relativnom ili apsolutnom putanjom do direktorijuma u koji ih treba smestiti; opcije se mogu različito zvati, zavisno od alata koji se koristi
-
postaviti u OMNIBOR_DIR promenljivu okruženja apsolutnu ili relativnu putanju do direktorijuma gde treba staviti OmniBOR informacije
Ukoliko se urade obe navedene stvari, prioritet ima opcija alata i OmniBOR informacije se smeštaju u direktorijum čija je putanja navedena u toj opciji.
Sada ćemo na jednom primeru pokazati kako rad sa OmniBOR konceptom može izgledati u praksi. S obzirom da je autor radio na OmniBOR implementacijama u GCC-u i u BinUtils-u (kao i u Patch alatu), razmotrićemo situaciju kada imamo izvorni fajl a.c koji zavisi samo od a.h fajla:

Od izvornog fajla a.c želimo da napravimo izvršni fajl a.out, generišući pritom OmniBOR informacije, najpre za prevođenje izvornog fajla u objektni fajl, a potom i za linkovanje tog fajla sa samim sobom u izvršni fajl.
Pošto želimo da omogućimo generisanje OmniBOR informacija i u GCC-u i u GNU linkeru, imamo dve mogućnosti:
-
prva je da postavimo OMNIBOR_DIR promenljivu okruženja, a zatim pokrenemo komandu
<path_to_gcc_bin_dir>/gcc -fuse-ld=bfd -B <path_to_binutils_bin_dir> a.c -o a.out
-
druga je da specificiramo i za GCC i za GNU linker odgovarajuće OmniBOR opcije (-frecord-omnibor=<dir> za GCC, odnosno --omnibor=<dir> za GNU linker)
<path_to_gcc_bin_dir>/gcc -fuse-ld=bfd -B <path_to_binutils_bin_dir> a.c
-frecord-omnibor=<dir> -Wl,--omnibor=<dir> -o a.out
U ovim komandama, <path_to_ gcc_bin_dir> je putanja do bin direktorijuma u kome se nalazi izvršni fajl pod imenom gcc za GCC koji podržava OmniBOR koncept, dok je <path_to_binutils_bin_dir> putanja do bin direktorijuma BinUtils-a koji podržava OmniBOR koncept. Argument OmniBOR opcija za GCC i BinUtils u slučaju 2) ne mora biti isti, ali ukoliko jeste, dobiće se identičan rezultat kao da je korišćena OMNIBOR_DIR promenljiva okruženja.
Pokretanjem bilo koje od ovih komandi dobija se izvršni fajl a.out i dva sporedna efekta: generisanje i ugrađivanje OmniBOR informacija.
Generisanje OmniBOR informacija
OmniBOR informacije se generišu u obliku OmniBOR Document fajlova koji se smeštaju u odgovarajući direktorijum. Svaki od alata kreira po jedan par OmniBOR Document fajlova, jedan sa SHA1, a drugi sa SHA256 heš funkcijom. Ovi fajlovi sadrže informacije o artefaktima koji su prosleđeni na ulaz alata. OmniBOR Document fajl se imenuje sopstvenim gitoid-om, nakon što se uklone njegova prva dva početna karaktera i smešta na odgovarajuće mesto prema sledećem formatu:
<omnibor_dir>/objects/gitoid_blob_sha{1, 256}/<first_two_chars>/
gde <first_two_chars> predstavlja prva dva heksadecimalna karaktera gitoid-a OmniBOR Document fajla. Zbog toga je i odlučeno da se OmniBOR Document fajl imenuje preostalim karakterima njegovog gitoid-a, umesto celim gitoid-om.
Za GCC, SHA1 OmniBOR Document fajl bi imao gitoid
“4bc8a1b3d6f77bd53e2aa8c0153fd79a591c4a11” i izgledao ovako:

Kao što se može primetiti, na početku se nalazi indikator koji ukazuje na to koja je heš funkcija korišćena prilikom generisanja OmniBOR Document fajla (u SHA256 OmniBOR Document fajlu bi tu stajalo “gitoid:blob:sha256”). Potom se za svaki od fajlova koji dolaze na ulaz GCC-a generiše po jedan red, koji sadrži reč “blob” i gitoid odgovarajućeg ulaznog fajla. Konkretno u ovom slučaju, ulazni fajlovi su a.c, a.h i sistemski fajl /usr/include/stdc-predef.h,koji se automatski dovodi na ulaz GCC alata.
Za GNU linker, SHA1 OmniBOR Document fajl bi imao gitoid
“b191b25eb7e6c96b9d4b16599a6e010d60b08d44” i izgledao ovako:

U ovom slučaju, na ulaz linkera je dovedeno 13 artefakata od čega je jedan privremeni objektni fajl koji je rezultat rada GCC alata, dok preostalih 12 predstavlja razne sistemske objektne fajlove, deljene objekte i biblioteke, koji nam trenutno nisu od interesa. Može se primetiti da linija koja se odnosi na pomenuti privremeni objektni fajl sadrži i “bom” deo. To je zbog toga što je jedino taj artefakt dobijen radom nekog alata koji podržava OmniBOR koncept (u ovom slučaju GCC-a). Samim tim, iz njega se mogu dohvatiti gitoid-i OmniBOR Document fajlova koji su generisani prilikom kreiranja tog artefakta i staviti u pomenuti “bom” deo u liniji koja odgovara tom artefaktu. Na ovaj način, dobija se ranije spomenuti ADG i održava informacija o načinu nastanka različitih artefakata, sve do izvornih fajlova.
Treba napomenuti da je i GNU asembler osposobljen da generiše OmniBOR informacije kada radi asembliranje ulaznog asemblerskog fajla u objektni fajl. Ipak, odlučeno je da se to ne čini u ovoj situaciji (kada se od izvornog fajla pravi objektni ili izvršni fajl) ukoliko je zadato da se generisanje OmniBOR informacija radi i u GCC-u i u GNU asembleru. Razlog za to je što GCC svakako izgeneriše validne OmniBOR informacije za objektni fajl (koji je ili krajnji rezultat rada ili ulazni fajl za linker), pa nema potrebe uvoditi dodatan nivo indirekcije kojim se ne dobijaju nikakve nove informacije. Ovo je samo implementacioni detalj, koji nije neophodan prema zvaničnoj OmniBOR specifikaciji.
Ugrađivanje OmniBOR informacija
Nakon što se izgenerišu OmniBOR Document fajlovi, potrebno je informaciju o njima na neki način povezati sa artefaktima koji su nastali kao rezultat procesa u kome su ti fajlovi kreirani. Pošto je u navedenom primeru rezultujući artefakt ELF fajl, povezivanje se postiže tako što se u posebnu ELF note sekciju ovog fajla, koja je nazvana “.note.omnibor”, upisuju SHA1 i SHA256 gitoid-i OmniBOR Document fajlova generisanih prilikom dobijanja tog artefakta. Na slici ispod je dat izgled ove sekcije:

Ukoliko se dalje dobijeni softverski objekat koristi kao ulaz u neki drugi alat, tada će taj alat moći da uzme gitoid-e iz njegove “.note.omnibor” sekcije, koje zatim može staviti u “bom” delove odgovarajućih linija OmniBOR Document fajlova koje on bude kreirao. Upravo ova veza između artefakta i njegovih OmniBOR informacija predstavlja temelj za kreiranje ADG grafova i korišćenje OmniBOR koncepta na predviđeni način.
Zaključak
Sve u svemu, OmniBOR predstavlja napredan koncept koji može da oblikuje budućnost identifikacije ranjivosti u softveru. Nadam se da je ovaj opis njegove strukture i osnovnih primena dovoljan da vas zainteresuje da pratite njegov dalji razvoj, a možda i da ga koristite u nekoj bližoj (ili daljoj) budućnosti. Hvala na pažnji!
Add comment