Zip bomba kako radi. Putinova arhivska bomba. Wordpress nas je osudio

💖 Sviđa vam se? Podijelite link sa svojim prijateljima
[Ažuriranje] Sada sam na nekoj obaveštajnoj listi jer sam napisao članak o nekoj vrsti "bombe", zar ne?

Ako ste ikada hostovali web stranicu ili administrirali server, vjerovatno ste dobro svjesni loših ljudi koji pokušavaju učiniti loše stvari vašoj imovini.

Kada sam prvi put ugostio svoju malu Linux kutiju sa SSH pristupom u dobi od 13 godina, pogledao sam dnevnike i svaki dan sam vidio IP adrese (uglavnom iz Kine i Rusije) kako pokušavaju da se povežu na moju slatku kutiju (koja je zapravo bila stari laptop ThinkPad T21 sa pokvarenim ekranom koji zuji ispod kreveta). Ove IP adrese sam prijavio njihovim ISP-ovima.

Zapravo, ako imate Linux server sa otvorenim SSH-om, možete sami vidjeti koliko se pokušaja povezivanja događa dnevno:

Grep "greške autentifikacije" /var/log/auth.log


Stotine neuspjelih pokušaja autorizacije, iako server uopće nema autorizaciju lozinke i radi na nestandardnom portu

Wordpress nas je osudio

U redu, da se razumijemo, skeneri web ranjivosti postojali su prije Wordpress-a, ali nakon što je platforma postala toliko popularna, većina skenera je počela provjeravati pogrešno konfigurirane wp-admin mape i nezakrpene dodatke.

Dakle, ako mala nova hakerska banda želi da dobije nove naloge, oni će preuzeti jedan od ovih alata za skeniranje i pokrenuti ga na gomili veb lokacija u nadi da će pristupiti nekom sajtu i unakaziti ga.


Uzorak dnevnika kada ih skenira Nikto alat

Zbog toga se svi serveri i administratori web stranica bave gigabajtima dnevnika punim pokušaja indeksiranja. pa sam mislio...

Možete li uzvratiti udarac?

Nakon eksperimentiranja s potencijalnom upotrebom IDS-a ili Fail2ban-a, podsjetio sam se na dobre stare ZIP bombe iz prošlosti.

Kakva je to ZIP bomba?

Kako se ispostavilo, ZIP kompresija je odlična u radu s podacima koji se ponavljaju, pa ako imate divovskog tekstualnu datoteku, ispunjen ponovljenim podacima kao i sve nule, vrlo dobro će se komprimirati. Mislim VEOMA dobro.

Kao što je pokazao 42.zip, moguće je komprimirati 4,5 petabajta (4.500.000 gigabajta) u 42 kilobajta. Kada pokušate da pogledate sadržaj arhive (raspakujte je ili raspakujte), verovatno ćete potrošiti sav prostor na disku ili RAM.

Kako baciti ZIP bombu na skener ranjivosti?

Nažalost, web pretraživači ne razumiju ZIP, ali razumiju GZIP.

Dakle, prva stvar koju ćemo uraditi je kreirati GZIP datoteku od 10 GB ispunjenu nulama. Možete napraviti mnogo ugniježđenih kompresija, ali počnimo s jednostavnim.

Dd if=/dev/zero bs=1M count=10240 | gzip > 10G.gzip


Pravljenje bombe i provjeravanje njene veličine

Kao što vidite, njegova veličina je 10 MB. Moglo je biti malo čvršće, ali za sada je dovoljno.

Sada instalirajmo PHP skriptu koja će je isporučiti klijentu.

Spremni!

Sada ga možemo koristiti kao jednostavnu odbranu:

Očigledno, ova skripta nije neka elegancija, ali nas može zaštititi od ranije spomenutih skriptnih klinaca, koji uopće nemaju pojma da je moguće promijeniti user-agent u crawlerima.

Dakle... Šta se dešava ako pokrenete ovu skriptu?


(ako ste testirali bombu na drugim uređajima/pretraživačima/skriptama, molim

Jedan vrlo zanimljiv i važan događaj desio se tiho i neprimjetno za uvredljive. Ruski predsjednik Vladimir Putin sastao se i razgovarao sa jednim od čelnika državne službe čije se ime rijetko pojavljuje u štampi. Ne, ova osoba nije tajni agent, iako po prirodi svoje djelatnosti ima pristup povjerljivim podacima, pa se čak može smatrati svojevrsnim "borcem nevidljivog fronta". Generalno, Putin je razgovarao sa šefom Federalne arhivske agencije Andrejem Artizovim.

Razgovor između šefa države i šefa agencije bio je poslovnog karaktera, čije bi moguće posljedice ponegdje mogle izazvati efekat eksplozije bombe, a u nekim slučajevima i detonaciju lične mlaznice.

Predsjednik je dao tihu izjavu da je odlučio da skine tajnost sa mnogih arhivskih dokumenata, štoviše, ukaz će biti potpisan istog dana. Osim toga, Putin je najavio prelazak Rosarhiva u direktnu potčinjenost predsjedniku Rusije, budući da su mnogi materijali odjela "od posebne vrijednosti i od globalnog značaja".

Šef agencije je pak obavijestio predsjednika da se u arhivskom fondu Rusije nalazi 500 miliona dosijea, te da "nikada u posljednjih nekoliko decenija nije obavljen planiran, organizovan rad na uklanjanju tajnosti kao što se sada radi".

Ključna stvar je da će odmah nakon deklasifikacije arhivski dokumenti biti dostupni na službenoj web stranici Ruskog arhiva, za koji je već napravljena posebna baza podataka.

Među arhivama koje su već skinute oznaku tajnosti nalaze se materijali kojima su domaći i strani istoričari dugo lizali usne: 1400 jedinstvenih Staljinovih direktiva, naređenja iz Glavnog štaba, naređenja s fronta, operativnih mapa, rezolucija i fotografija tog vremena, donedavno čuvanih u arhive pod naslovom "strogo poverljivo".

Za historičare se može samo iskreno radovati, poželjeti im svježe i zanimljive radove, koji će se temeljiti na gore navedenim dokumentima, ali samo deklasifikacija neće utjecati na jednu vojno-istorijsku temu.

Zanimljive detalje iznosi izvor blizak Ruskom arhivu: „Koliko ja znam iz arhivskog odeljenja, radi se o periodu od 1930. do 1989. godine. Ima slučajeva, izvinite, doušnika - kao i nevino potisnutih, sa vrlo zanimljivim prezimenima. Biće podataka o svemirskom i vojnom razvoju koji se već mogu izvesti. Osim toga, uklanjaju se povjerljivi podaci o toku bitaka, naređenjima i obavještajnim podacima dobijenim tokom Velikog otadžbinskog rata, kao io međudržavnim odnosima tokom Hladnog rata.

I dodaje vrlo ozbiljno: „Neki dokumenti će iznenaditi društvo. Morate znati sopstvenu istoriju, kakva god ona bila.

Arhivi imaju dugo pamćenje i nose potencijalni naboj koji nije gori od hidrogenske bombe. Nije slučajno što kod nas „slučaj maršala“ i „slučaj doktora“ i dalje ostaju poverljivi, dugo stvarajući osnov za svakakve spekulacije. Ne tako davno, u Velikoj Britaniji se posebna komisija bavila arhivskim dokumentima čiji se period tajnosti bližio kraju, ali je odlučeno da se režim tajnosti produži za još 50 godina na osnovu podataka o predratnim kontaktima britanskih obavještajaca sa nacistički SD.

Rezerva da će "neki dokumenti iznenaditi javnost" nije slučajna. Krajem 1980-ih, kako u Rusiji, tako iu republikama bivšeg SSSR-a, na talasu "demokratizacije" na vlast su došli različiti ljudi.

Mnogi pokazuju zadivljujuću političku vitalnost, uprkos očiglednom nedostatku menadžerskog talenta i težnji da pouče ljude o demokratiji sa njihove tačke gledišta.

U bliskom inostranstvu, bivši lideri "narodnih frontova", koji su promenili svoj pogled na svet iz antisovjetskog u antiruski, čvrsto su se držali vlasti i sa svoje teritorije vode neprijateljsku politiku prema Rusiji - od organizovanja kongresa svih vrsta. odbačenih iz "Otvorene Rusije" za obuku profašističkih militanata i pružanje vojne pomoći Banderi.

Evropska zajednica, kao i građani ovih limitrofa, biće zainteresovani da saznaju iz deklasifikovanih dokumenata Rosarhiva – ko su od vrednih pažnje „evrodemokrata“ bili doušnici KGB-a. Glasine da su bivši vođa Nacionalnog fronta Litvanije Landsbergis i sadašnja predsjednica Dalia Grybauskaite „kucale“ u KGB u vrijeme maglovite mladosti - puna je zemlja. Sada će se o ovoj strani njihove biografije, vjerujem, moći saznati iz originalnog izvora.

Možete ogovarati da je "bilo davno, a nije istina", "prošlost je porasla", koliko god želite, ali nemojte podcjenjivati ​​razornu moć takvih otkrića.

Može se prisjetiti kako je prošle godine paket dokumenata koje je otkrio Institut za nacionalno sjećanje, o suradnji Lecha Walese (pod operativnim porivom "Bolek"), spektakularno pocijepan u poljskoj štampi u jeku njegovih aktivnosti u Gdanjsku. brodogradilište. Informativna eksplozija nije ostavila kamen na kamenu na slici ikone, "Polja br. 1", lidera Solidarnosti, dobitnika Nobelove nagrade za mir i prvog predsjednika antisovjetske Poljske. Walesa je od sada samo brkati debeli starac, ruševina prošlog vremena, čija se sramota može vidjeti vlastitim očima u vidu 17 priznanica postavljenih u istom Institutu nacionalnog pamćenja za primanje novca za kucanje -knock-information prosleđen specijalnim službama.

Ostaje samo žaliti što arhivska "bomba" nije eksplodirala ispod dna agenta "Boleka" 1980-ih, kada su on i njegova "Solidarnost", koja je pjevala sa zapadnim obavještajnim službama, uzdrmala socijalističku Poljsku.

I domaće liberale mogu čekati mnoga zanimljiva iznenađenja. Njihov vijugavi životni put u mnogome je sličan putu Walese do vrhova moći. Na našu duboku žalost, KGB nije žurio da razotkrije reformisane doušnike iz mnogo razloga, među kojima etički nisu bili na poslednjem mestu. Uostalom, ako otkrijete agenta, posebno dobrovoljnog, ko će onda sarađivati? Nećete daleko stići sa agentima koji su uhvaćeni u činjenju nepristojnih radnji i regrutovani po ovoj osnovi.

U medijima se probijaju nezvanične informacije da su "istaknute ličnosti liberalno-demokratskog pokreta u Rusiji" dobrovoljno sarađivale sa sovjetskim tajnim službama, iz sebičnih motiva: zanimljivih poslovnih putovanja, napredovanja u karijeri, prestižnog posla itd.

Može se samo zamisliti kakva su škripa zmija bila razna kreativna udruženja pisaca, kazališnih ličnosti i filmaša.

Za mnoge kritičare SSSR-a i sovjetskog sistema, roditelji nisu bili samo istaknute partijske ili ekonomske ličnosti, već su služili i u organima NKVD-MGB-KGB-a, pa čak i lično učestvovali u represijama.

Naravno, djeca nisu odgovorna za svoje očeve, ali postaje odvratno u duši kada se prefarbani potomci odvode da izlažu i trgaju pokrivače, koji ne žele da se sjećaju prošlosti svojih roditelja, već su jednom, bez imalo grižnje savjesti, uzeli prednost njihovog visokog položaja, kao odskočna daska za ličnu svetlu budućnost.

Arhive sa kojih je skinuta oznaka tajnosti mogu uticati na postrojavanje snaga u banditskoj Ukrajini. Može se prisjetiti kako su brojni dokumenti koje je na društvenim mrežama objavila Miroslava Berdnik i prije puča na Majdanu, a koji se tiču ​​saradnje vođa OUN-a sa Ministarstvom državne sigurnosti i Ministarstvom unutrašnjih poslova, izazvali napade grčenja i fontane. proljev u grlu među navijačima mrtvih Bandere. Svidomiti su psovali, fotokopije dokumenata nazivali „FB lažnjacima“, ali nisu mogli da raspravljaju ni sa jednim razlogom.

Zašto je to važno? Ukrajinski radikalni nacionalizam je bezrezervno zlo. Ali to ispovijedaju različiti ljudi. Među modernim pripadnicima OUN-a ima svojih idealista koji žele da očiste ukrajinski nacionalizam od najodvratnijih ličnosti Bandere i Šuheviča, budući da su se dugo i nepovratno kompromitovali kao hitlerovske marionete i kaznitelji. Kako god bilo, ali poslijeratna sovjetska obavještajna služba dobro je razumjela osjećaje njemačkih nacionalista, koji su se jasno odvojili od nacista i pristalica generala Gehlena, koji je potpao pod Amerikance. Njemački nacionalisti, koji su Bismarcka smatrali svojim idolom, nakon što su preživjeli užase rata i vidjeli kako Amerikanci guraju SRJ u novi rat sa SSSR-om, radije su radili za sovjetske i istočnonjemačke obavještajne službe. Ovu tačku svakako vrijedi razmotriti.

S druge strane, Ukrajina je puna vatrenih neobanderista koji ne pate od viška gađenja, koji se ne plaše nijednog dokumentarnog dokaza o saradnji svojih idola sa nacističkim tajnim službama. A šta ako se objave dokumenti sa kojih je skinuta oznaka povjerljivosti u kojima se kaže da su njihovi idoli, poput Vasila Kuka, procurili MGB-u informacije o njihovoj „braći“ koja sjede u skrovištima?

Šta ako se odjednom pokaže da su svakakvi "desničari" i "kvadrati" kasnog sovjetskog perioda kucali na KGB da ublaže zatvorski režim, za dodatni paket slanine od kuće ili pakovanje krhotine od kamp štand? Hoće li Banderin "spilnota" koji svuda vidi dugu ruku Moskve, FSB-a i Putina lično izdržati takav test čvrstoće uvjerenja?

Informacije ove vrste mogu izazvati snažno oslobađanje termonuklearne plazme iz svidomskih dupa, čiji se vlasnici hvale "nacionalnom čistoćom" i "svidomom". Otkrovenja idola mogu naterati nekoga da ustukne i promeni mišljenje.

Bilo bi zanimljivo saznati o dvostrukom životu vođa samoproglašenog "Medžlisa", kao i drugih podlih ličnosti, koje čame pod teretom "savijesti nacije" samovoljno preuzete na sebe.

Pa pod čijim ličnim dupetom će eksplodirati prva arhivska "bomba"? Ko će ići sa "lokomotivom" odmotavajući dugi lanac otkrića?


*Postoje dvije verzije 42.zip: stara ima 42.374 bajta, a novija 42.838 bajtova. Razlika je u tome što novi zahtijeva lozinku prije raspakivanja. Upoređujemo samo sa starom verzijom. Evo kopije datoteke ako vam je potrebna: 42.zip .

Zip bombe moraju prevazići činjenicu da DEFLATE algoritam kompresije koji najčešće podržavaju parseri ne može premašiti omjer kompresije od 1032 prema 1. Iz tog razloga, zip bombe se obično oslanjaju na rekurzivnu dekompresiju ugnježđujući zip datoteke unutar zip datoteka kako bi dobili dodatni omjer 1032 sa svakim slojem. Ali trik funkcionira samo u implementacijama koje se rekurzivno raspakuju, a većina ne. Najpoznatija 42.zip bomba se proširuje na nevjerovatnih 4,5 PB kada se svih šest slojeva rekurzivno dekompresuje, ali ima slabih 0,6 MB na gornjem sloju. Zip kvinovi, poput onih od Coxa i Ellingsena, proizvode svoju kopiju i tako se neograničeno šire kada se rekurzivno dekomprimiraju. Ali takođe su savršeno sigurni kada se jednom raspakuju.

Ovaj članak pokazuje kako kreirati nerekurzivnu zip bombu čiji omjer kompresije premašuje ograničenje DEFLATE od 1032. Radi tako što se datoteke unutar zip kontejnera preklapaju kako bi se upućivale na "jezgro" visoko komprimiranih podataka u više datoteka bez pravljenja više kopija. Izlazna veličina zip bombe raste kvadratno od ulazne veličine; tj. omjer kompresije se poboljšava kako se veličina bombe povećava. Dizajn zavisi od karakteristika zip i DEFLATE: nije direktno prenosiv na druge formate datoteka ili algoritme kompresije. Bomba je kompatibilna sa većinom zip parsera, osim sa "striming" parserima, koji analiziraju datoteke u jednom prolazu bez provjere centralnog direktorija zip datoteke. Pokušavamo uravnotežiti dva suprotstavljena cilja:

  • Povećajte omjer kompresije. Definiramo omjer kompresije kao zbir veličina svih datoteka u arhivi podijeljen s veličinom same zip datoteke. Ovo ne uključuje nazive datoteka ili druge metapodatke sistema datoteka, već samo sadržaj.
  • Održavajte kompatibilnost. Zip je složen format i parseri se razlikuju, posebno u rubnim slučajevima i dodatnim funkcijama. Nemojte koristiti trikove koji rade samo s određenim parserima. Zabilježit ćemo neke načine za poboljšanje učinkovitosti zip bombe uz određeni gubitak kompatibilnosti.

Struktura zip datoteke

Zip fajl se sastoji od centralni imenik linkovi na datoteke.

Centralni direktorij je na kraju zip datoteke. Ovo je lista zaglavlja centralnog direktorija. Svako zaglavlje centralnog direktorija sadrži metapodatke jedne datoteke, kao što su ime datoteke i CRC-32 kontrolni zbroj, te povratni pokazivač na zaglavlje lokalnog fajla. Zaglavlje centralnog direktorija ima dužinu od 46 bajtova plus dužina imena datoteke.

Datoteka se sastoji od lokalnog zaglavlja datoteke praćenog komprimiranim podacima datoteke. Dužina lokalnog zaglavlja datoteke je 30 bajtova plus dužina imena datoteke. Sadrži redundantnu kopiju metapodataka iz zaglavlja centralnog direktorija i veličine komprimiranih i nekomprimiranih datoteka podataka iza njega. Zip je format kontejnera, a ne algoritam kompresije. Podaci svake datoteke se komprimiraju pomoću algoritma navedenog u metapodacima, obično DEFLATE.

Ovaj opis zip formata izostavlja mnoge detalje koji nisu potrebni za razumijevanje zip bombe. Pogledajte odjeljak 4.3 APPNOTE.TXT ili Florian Buchholz "PKZip File Structure" za potpune detalje, ili pogledajte .

Značajna suvišnost i mnoge nejasnoće u zip formatu otvaraju mogućnosti za nestašluke svih vrsta. Zip bomba je samo vrh ledenog brega. Linkovi za dalje čitanje:

$ python3 -m zipfile -e preklapanje.zip . Traceback (posljednji poziv posljednji): ... __main__.BadZipFile: Ime datoteke u direktoriju "B" i zaglavlje b"A" se razlikuju.
Zatim ćemo pogledati kako izmijeniti konstrukciju za konzistentnost naziva datoteke uz zadržavanje većine prednosti preklapanja datoteka.

Drugo otkriće: citiranje zaglavlja lokalnih datoteka

Moramo odvojiti lokalna zaglavlja datoteke za svaki fajl, dok još uvijek ponovno koristimo jedno jezgro. Jednostavno spajanje svih zaglavlja ne radi, jer će zip parser pronaći zaglavlje lokalnog fajla tamo gdje očekuje početak DEFLATE toka. Ali ideja će uspjeti, uz nekoliko promjena. Koristit ćemo DEFLATE funkciju nekomprimiranih blokova da "citiramo" zaglavlja lokalnih datoteka tako da izgledaju kao dio istog DEFLATE toka koji završava u kernelu. Svako lokalno zaglavlje datoteke (osim prvog) će se tumačiti na dva načina: kao kod (dio strukture zip datoteke) i kao podatak (dio sadržaja datoteke).

DEFLATE tok je niz blokova, gdje svaki blok može biti komprimiran ili nekomprimiran. Obično mislimo samo na komprimirane blokove, na primjer, kernel je jedan veliki komprimirani blok. Ali postoje i nekomprimovani koji počinju sa 5-bajtnim zaglavljem s poljem dužine, što jednostavno znači: "ispišite sljedeće n bajtova doslovno. Dekomprimiranje nekomprimovanog bloka znači samo uklanjanje 5-bajtnog zaglavlja. Komprimirani i nekomprimirani blokovi mogu se slobodno miješati u DEFLATE streamu. Izlaz je konkatenacija rezultata raspakivanja svih blokova po redu. Termin "nekomprimirano" je relevantan samo na nivou DEFLATE; podaci o fajlu se i dalje smatraju "komprimiranim" na zip nivou, bez obzira koji blokovi se koriste.

Najlakši način da zamislite ovu konstrukciju je unutrašnje preklapanje, od posljednjeg fajla do prvog. Počinjemo umetanjem kernela koji će formirati kraj datoteke podataka za svaki fajl. Dodavanje zaglavlja lokalnog LFH datoteke N i naziv centralnog imenika CDH N, što ukazuje na to. Postavite polje metapodataka komprimirane veličine na LFH N i CDH N na komprimiranoj veličini kernela. Sada dodajemo nekomprimirano zaglavlje bloka od 5 bajta (zeleno na dijagramu), čije je polje dužine jednako veličini LFH N. Dodavanje drugog lokalnog zaglavlja LFH datoteke N−1 i zaglavlje centralnog direktorija CDH N−1 , što ukazuje na to. Postavite polje metapodataka "komprimirana veličina" kao novo zaglavlje komprimirane veličine kernela plus nekomprimovana veličina zaglavlja bloka (5 bajtova) plus LFH veličina N .

Trenutno zip datoteka sadrži dvije datoteke pod nazivom Y i Z. Hajde da prođemo kroz ono što će parser vidjeti kada analizira. Pretpostavimo da je komprimirana veličina kernela 1000 bajtova, a veličina LFH N- 31 bajt. Počevši od CDH N−1 i slijedite pokazivač na LFH N-1 . Ime prve datoteke je Y, a komprimirana veličina njene datoteke podataka je 1036 bajtova. Kada tumačimo sljedećih 1036 bajtova kao DEFLATE tok, prvo nailazimo na 5-bajtno nekomprimirano zaglavlje bloka koje kaže da se kopira sljedeći 31 bajt. Napišite sljedeći 31 bajt, koji su LFH N, koji dekomprimujemo i dodajemo u datoteku Y. Krećući se dalje u DEFLATE streamu, nalazimo komprimirani blok (kernel), koji dekomprimujemo u datoteku Y. Sada smo došli do kraja komprimiranih podataka i završili sa datotekom Y.

Prelazeći na sljedeći fajl, pratimo pokazivač iz CDH N do LFH N i pronađite datoteku pod nazivom Z, čija je komprimirana veličina 1000 bajtova. Interpretirajući ovih 1000 bajtova kao DEFLATE tok, odmah nailazimo na komprimirani blok (opet kernel) i dekompresujemo ga u datoteku Z. Sada smo stigli do kraja konačnog fajla i gotovi smo. Z izlazna datoteka sadrži raspakovani kernel; izlazna datoteka Y je ista, ali dodatno ima prefiks od 31 bajta LFH N .

Konstrukciju završavamo ponavljanjem postupka citiranja sve dok zip arhiva ne sadrži potreban broj datoteka. Svaki novi fajl dodaje zaglavlje centralnog direktorijuma, zaglavlje lokalnog fajla i nekomprimovani blok da citira zaglavlje lokalnog fajla koji sledi. Komprimirani podaci datoteke su tipično lanac nekomprimiranih DEFLATE blokova (citiranih lokalnih zaglavlja datoteke) nakon kojih slijedi komprimirano jezgro. Svaki bajt u kernelu doprinosi oko 1032 N na izlaznu veličinu, jer je svaki bajt dio svega N datoteke. Izlazne datoteke su također različitih veličina: starije su veće od kasnijih jer više citiraju zaglavlja lokalnih datoteka. Sadržaj izlaznih datoteka nema mnogo smisla, ali niko nije rekao da treba.

Ova preklapajuća konstrukcija citiranja ima bolju kompatibilnost od konstrukcije potpunog preklapanja iz prethodnog odjeljka, ali kompatibilnost dolazi po cijenu kompresije. Tamo je svaka dodana datoteka vrijedila samo zaglavlje centralnog direktorija, ovdje vrijedi zaglavlje centralnog direktorija, zaglavlje lokalnog fajla i još 5 bajtova za zaglavlje citata.

Optimizacija

Pošto smo dobili osnovni dizajn zip bombe, pokušaćemo da je učinimo što efikasnijom. Želimo da odgovorimo na dva pitanja:
  • Koji je maksimalni omjer kompresije za datu veličinu zip datoteke?
  • Koji je maksimalni omjer kompresije s obzirom na ograničenja zip formata?

Core Compression

Za nas je korisno da kompresujemo jezgru što je više moguće, jer se svaki raspakovani bajt množi sa N. U tu svrhu koristimo prilagođeni DEFLATE kompresor koji se zove bulk_deflate, specijaliziran za komprimiranje niza ponovljenih bajtova.

Svi pristojni DEFLATE arhivi pristupaju omjeru kompresije od 1032 na beskonačnom nizu ponovljenih bajtova, ali mi brinemo o specifičnoj veličini. U našoj veličini arhive, bulk_deflate sadrži više podataka od arhivatora opće namjene: oko 26 KB više od zlib-a i Info-ZIP-a i oko 15 KB više od Zopflija, koji žrtvuje brzinu radi kvaliteta kompresije.

Cijena visokog bulk_deflate omjera kompresije je nedostatak svestranosti. Može samo komprimirati nizove ponovljenih bajtova i samo određene dužine, naime 517 + 258 k za cijeli broj k≥ 0. Pored dobre kompresije, bulk_deflate je brz, obavlja posao u skoro istom vremenu bez obzira na veličinu ulaznih podataka, osim posla stvarnog pisanja kompresovanog stringa.

Imena datoteka

Za naše potrebe, nazivi datoteka su praktički mrtvi teret. Iako doprinose veličini izlaza time što su dio citiranih lokalnih zaglavlja datoteke, bajt u imenu datoteke doprinosi mnogo manje od bajta u kernelu. Želimo da nazivi fajlova budu što kraći, ali različiti, imajući na umu kompatibilnost.

Svaki bajt potrošen na ime datoteke znači dva bajta koja nisu potrošena na kernel (dva, jer se svako ime datoteke pojavljuje dvaput: u zaglavlju centralnog direktorija i u zaglavlju lokalne datoteke). Bajt naziva fajla rezultira samo ( N+ 1) / 4 bajta izlaza, dok se bajt u kernelu računa kao 1032 N. Primjeri: , , .

Prvo razmatranje kompatibilnosti je kodiranje. Specifikacija zip formata navodi da imena datoteka treba tumačiti kao CP 437 ili UTF-8 ako je postavljen određeni bit zastave (APPNOTE.TXT, Dodatak D). Ovo je glavna tačka nekompatibilnosti između zip parsera, koji mogu tumačiti imena datoteka u nekom fiksnom ili specifičnom kodiranju za lokalizaciju. Stoga, radi kompatibilnosti, bolje je ograničiti se na znakove sa istim kodiranjem u CP 437 i UTF-8. Naime, radi se o 95 US-ASCII znakova za ispis.

Takođe smo vezani ograničenjima imenovanja sistema datoteka. Neki sistemi datoteka ne razlikuju velika i mala slova, tako da se "a" i "A" ne smatraju različitim imenima. Uobičajeni sistemi datoteka kao što je FAT32 ne dozvoljavaju određene znakove kao što su "*" i "?".

Kao siguran, ali ne nužno i optimalan kompromis, naša zip bomba će koristiti nazive datoteka iz abecede od 36 znakova koja ne uključuje posebne ili mješovite znakove velikih i malih slova:

0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Imena fajlova se generišu na očigledan način, sve pozicije redom, sa pozicijom koja se dodaje na kraju petlje:

"0", "1", "2", …, "Z", "00", "01", "02", ..., "0Z", ..., "Z0", "Z1", "Z2", …, "ZZ", "000", "001", "002", …
Postoji 36 imena datoteka koje su dugačke jedan znak, 362 imena datoteka koje su dugačke dva znaka, itd. Četiri bajta su dovoljna za 1.727.604 različita imena datoteka.

S obzirom da će imena datoteka u arhivi obično imati različite dužine, koji je najbolji način da ih rasporedite: od najkraćeg do najdužeg ili obrnuto? Ako malo razmislite, bolje je najduža imena staviti na kraj. Ovo sortiranje dodaje preko 900MB izlaza u zblg.zip, u poređenju sa najdužim prema najkraćim redosledom. Međutim, ovo je manja optimizacija, jer je 900 MB samo 0,0003% ukupne veličine izdanja.

Veličina kernela

Preklapajuća konstrukcija citiranja omogućava vam da postavite komprimovanu jezgru podataka i zatim je jeftino kopirate iznova i iznova. Za određenu veličinu zip datoteke X, koliko prostora je optimalno za pohranjivanje kernela, a koliko za kreiranje kopija?

Da biste pronašli optimalnu ravnotežu, trebate optimizirati samo jednu varijablu N, broj datoteka u zip arhivi. Svaka vrijednost N zahtijeva određenu količinu nadopterećenja za zaglavlja centralnog direktorija, zaglavlja lokalnih datoteka, zaglavlja blokova navoda i imena datoteka. Ostatak prostora će zauzeti jezgro. Zbog N mora biti cijeli broj i možete uklopiti samo određeni broj datoteka prije nego što veličina jezgre padne na nulu, samo provjerite svaku moguću vrijednost N i odaberite onaj koji vam daje najviše rezultata.

Primjena procedure optimizacije na X= 42 374 za 42.zip pronalazi maksimum na N= 250. Ovih 250 fajlova zahtevaju 21.195 bajtova nadzemnog opterećenja, ostavljajući 21.179 bajtova za kernel. Kernel ove veličine se raspakuje u 21,841,249 bajtova (omjer 1031,3 prema 1). 250 kopija dekomprimovanog kernela plus nekoliko navedenih zaglavlja lokalnih datoteka daje ukupan dekomprimirani izlaz od 5,461,307,620 bajtova i omjer kompresije od 129,000.

CRC-32 se može modelirati kao državni stroj koji ažurira 32-bitni statusni registar za svaki ulazni bit. Osnovne operacije ažuriranja za bitove 0 i 1 su:

Uint32 crc32_update_0(uint32 state) ( // Pomaknite najmanji bitni bit. bit b = stanje & 1; stanje = stanje >> 1; // Ako je pomaknuti bit bio 1, XOR sa CRC-32 konstantom. ako (b == 1) stanje = stanje ^ 0xedb88320; vrati stanje; ) uint32 crc32_update_1(uint32 stanje) ( // Uradi kao za 0 bit, zatim XOR sa CRC-32 konstantom. return crc32_update_0(state) ^ 0xedb883
Ako statusni registar predstavljate kao binarni vektor od 32 elementa i koristite XOR za sabiranje i množenje, tada je crc32_update_0 linearno preslikavanje; tj. može se predstaviti kao množenje binarnom prijelaznom matricom 32×32. Da vidite zašto, imajte na umu da je množenje matrice vektorom jednostavno zbrajanje stupaca matrice nakon množenja svake kolone odgovarajućim elementom vektora. Stanje operacije pomaka >> 1 jednostavno uzima svaki bit i vektor stanja i množi ga vektorom koji je svuda nula osim za bit i− 1 (numeracija bitova s ​​desna na lijevo). Relativno govoreći, konačno stanje XOR ^ 0xedb88320 se javlja samo kada je bit b jednak jedan. Ovo se može zamisliti kao prvo množenje b sa 0xedb88320, a zatim XOR uvođenje u to stanje.

Također, crc32_update_1 je samo crc32_update_0 plus (XOR) konstanta. Ovo čini crc32_update_1 afinom transformacijom: množenjem matrice praćeno mapiranjem (tj. zbrajanjem vektora). Množenje i preslikavanje matrice možemo predstaviti u jednom koraku ako povećamo dimenzije matrice transformacije na 33x33 i dodamo dodatni element vektoru stanja, koji je uvijek 1 (takva reprezentacija se zove homogene koordinate).


33×33 transformacijske matrice M 0 i M 1 , koje izračunavaju promjenu stanja CRC-32 koju vrše bitovi 0 i 1, respektivno. Vektori stupaca se pohranjuju sa najznačajnijim bitom na dnu: čitajući prvi stupac odozdo prema gore, vidite polinomsku konstantu CRC-32 edb8832016 = 111 011 011 0111 0001 0000011 001 00000 2 . Dvije matrice se razlikuju samo u završnoj koloni, koja predstavlja translacijski vektor u homogenim koordinatama. U M 0 translacija je nula, a u M 1 je edb88320 16 , CRC-32 polinomska konstanta. One iznad dijagonale predstavljaju stanje operativnog stanja >> 1

Obje operacije crc32_update_0 i crc32_update_1 mogu biti predstavljene matricom prijelaza 33x33. Prikazane su matrice M 0 i M 1. Prednost matrične reprezentacije je u tome što se matrice mogu množiti. Pretpostavimo da želimo da vidimo promjenu stanja napravljenu obradom ASCII karaktera "a", čija je binarna reprezentacija 01100001 2 . Možemo predstaviti kumulativnu promjenu stanja CRC-32 ovih osam bitova u jednoj matrici transformacije:


I možemo predstaviti promjenu stanja niza ponovljenih "a" množenjem mnogo kopija M a - podizanjem matrice na stepen. To možemo učiniti brzo koristeći algoritam brzog eksponencijaliranja, koji izračunava M n u samo log 2 n koraka. Na primjer, evo matrice promjene stanja reda od 9 znakova "a":
Algoritam brzog množenja matrice je koristan za izračunavanje M kernela, matrice za nekompresovano jezgro, jer je kernel niz ponovljenih bajtova. Da biste dobili kontrolnu sumu CRC-32 iz matrice, pomnožite matricu sa nultim vektorom (nulti vektor je u homogenim koordinatama, tj. 32 nule praćene jedinicom; ovdje izostavljamo manju komplikaciju pre- i naknadne obrade kontrolne sume za konzistentnost). Da bismo izračunali kontrolnu sumu za svaku datoteku, radimo unatrag. Počevši od inicijalizacije M:= M kernel. Kontrolna suma kernela je ujedno i konačna kontrolna suma datoteke N, pa množimo M na nulti vektor i pohraniti rezultujuću kontrolnu sumu u CDH N i LFH N . Podaci o fajlu N−1 isto kao i podaci o fajlu N, ali sa dodatkom LFH N prefiksa. Stoga izračunavamo , matricu prijelaza stanja za LFH N i ažuriramo . Sad M predstavlja kumulativnu promjenu stanja od LFH N obrade iza kernela. Izračunajte kontrolnu sumu za datoteku N−1, opet množenje M na nulti vektor. Nastavljamo proceduru akumulacijom matrica promjena stanja M dok se svi fajlovi ne obrađuju.

Proširenje: Zip64

Prethodno smo naišli na problem proširenja zbog ograničenja zip formata - bilo je nemoguće izdati više od 281TB, bez obzira na to koliko je zip datoteka bila pametno upakovana. Moguće je prevazići ova ograničenja korištenjem Zip64, proširenja zip formata koje povećava veličinu nekih polja zaglavlja na 64 bita. Podrška za Zip64 nikako nije univerzalna, ali je jedno od najčešće implementiranih ekstenzija. Što se tiče omjera kompresije, efekat Zip64 je povećanje veličine zaglavlja centralnog direktorija sa 46 na 58 bajtova, a veličine zaglavlja lokalnog direktorija sa 30 na 50 bajtova. Gledajući formulu za optimalni faktor ekspanzije u pojednostavljenom modelu, možemo vidjeti da Zip64 zip bomba i dalje raste kvadratno, ali sporije zbog većeg nazivnika - to se može vidjeti na donjem dijagramu. Zbog gubitka kompatibilnosti i sporijeg rasta, gotovo sva ograničenja veličine datoteke su uklonjena s nas.

Recimo da želimo zip bombu koja se širi na 4.5PB kao 42.zip. Koliko velika treba da bude arhiva? Binarnim pretraživanjem nalazimo da je minimalna veličina takve datoteke 46 MB.

  • zbxl.zip 46 MB → 4,5 PB (Zip64, manje kompatibilan)
zipbomb --mode=quoted_overlap --num-files=190023 --compressed-size=22982788 --zip64 > zbxl.zip
4,5 petabajta - otprilike isto toliko podataka zabilježio je Event Horizon Telescope za prvu sliku crne rupe: stalci i stalci sa tvrdim diskovima u data centru.

Sa Zip64, više nije zanimljivo razmatrati maksimalni omjer kompresije, jer možemo samo nastaviti povećavati veličinu zip datoteke i omjer kompresije zajedno s njim, sve dok čak ni komprimirana zip datoteka ne postane pretjerano velika. Interesantan prag je, međutim, 264 bajta (18 EB ili 16 EiB) - toliko podataka neće stati u većinu fajl sistema. Binarno pretraživanje pronalazi najmanju zip bombu koja proizvodi barem toliko izlaza: sadrži 12 miliona datoteka i 1,5 GB komprimirano jezgro. Ukupna veličina zip datoteke je 2,9 GB i dekompresuje se u 264+11727895877 bajtova sa omjerom kompresije od preko 6,2 milijarde prema jedan. Nisam postavio ovu datoteku za preuzimanje, ali možete je sami generirati koristeći . Ima fajlove takve veličine da je otkrivena čak i greška u Info-ZIP UnZip 6.0.

Zipbomb --mode=quoted_overlap --num-files=12056313 --compressed-size=1482284040 --zip64 > zbxxl.zip

Ekstenzija: bzip2

DEFLATE je najčešći algoritam kompresije za zip format, ali to je samo jedna od mnogih opcija. Vjerovatno drugi najčešći algoritam je bzip2. Iako nije tako kompatibilan kao DEFLATE. Teoretski, bzip2 ima maksimalan omjer kompresije od oko 1,4 miliona prema jedan, što omogućava da se kernel bolje spakuje.

Bzip2 prvo kodira kodiranje dužine runde, smanjujući dužinu niza ponovljenih bajtova za faktor 51. Podaci se zatim dijele na blokove od 900 KB i svaki blok se kompresuje zasebno. Teoretski, jedan blok se može komprimirati na 32 bajta. 900.000 × 51 / 32 = 1.434.375.

Na stranu gubitke kompatibilnosti, da li bzip2 dozvoljava efikasniju bombu?

Da - ali samo za male datoteke. Problem je u tome što bzip2 nema ništa poput nekomprimiranih blokova DEFLATE koje smo koristili da citiramo zaglavlja lokalnih datoteka. Prema tome, nije moguće preklapati datoteke i ponovo koristiti jezgro - svaki fajl mora napisati svoju kopiju, tako da ukupni omjer kompresije neće biti bolji od omjera za bilo koji pojedinačni fajl. Na grafikonu ispod, možemo vidjeti da, bez preklapanja, bzip2 nadmašuje DEFLATE samo za datoteke veličine oko megabajta.

Jedina preostala nada je za alternativni način citiranja bzip2 zaglavlja, o čemu se govori u sljedećem odjeljku. Takođe, ako znate da određeni zip parser podržava bzip2 I dozvoljava nepodudaranje naziva datoteke, možete koristiti potpunu konstrukciju nadjačavanja koja ne mora biti stavljena u navodnike.

Poređenje omjera kompresije različitih zip bombi. Obratite pažnju na logaritamske ose. Svaka konstrukcija je prikazana sa i bez Zip64. Konstrukcije bez preklapanja imaju linearnu brzinu rasta, što se vidi iz konstantnog omjera osi. Vertikalni pomak bzip2 grafa znači da je omjer kompresije bzip2 oko hiljadu puta veći od omjera DEFLATE. Navedene DEFLATE konstrukcije imaju kvadratnu stopu rasta, o čemu svjedoči iskrivljenost od 2:1. Zip64 varijanta je nešto manje efikasna, ali dozvoljava više od 281TB. Grafovi za bzip2 sa navođenjem kroz dodatno polje mijenjaju se iz kvadratnog u linearni kada se dostigne ili maksimalna veličina datoteke (2 32 −2 bajta) ili maksimalni dozvoljeni broj datoteka

Proširenje: citiranje putem dodatnog polja

Do sada smo koristili funkciju DEFLATE za citiranje zaglavlja lokalnih datoteka i upravo smo vidjeli da ovaj trik ne radi u bzip2. Međutim, postoji alternativni način citiranja, nešto ograničeniji, koji koristi samo funkcije zip formata i ne ovisi o algoritmu kompresije.

Na kraju strukture zaglavlja lokalne datoteke nalazi se dodatno polje varijabilne dužine za pohranjivanje informacija koje se ne uklapaju u normalna polja zaglavlja (APPNOTE.TXT, odjeljak 4.3.7). Dodatne informacije mogu uključivati, na primjer, vremensku oznaku ili Unix uid/gid. Zip64 informacije se također pohranjuju u dodatnom polju. Dodatno polje je predstavljeno kao struktura dužina-vrijednost; ako povećate dužinu bez dodavanja vrijednosti, tada će dodatno polje uključiti ono što se nalazi iza njega u zip datoteci, odnosno sljedeće lokalno zaglavlje datoteke. Koristeći ovu metodu, svako lokalno zaglavlje datoteke može "citirati" sljedeća zaglavlja tako što će ih umotati u svoje opciono polje. U poređenju sa DEFLATE, ovdje postoje tri prednosti:

  1. Citiranje preko dodatnog polja zahtijeva samo 4 bajta umjesto 5, ostavljajući više prostora za kernel.
  2. Ne povećava veličinu datoteka, što znači veći kernel, s obzirom na ograničenja zip formata.
  3. Pruža bzip2 citiranje.
Uprkos ovim prednostima, citiranje kroz dodatna polja je manje fleksibilno. Ovo nije lanac, kao u DEFLATE: svako zaglavlje lokalnog fajla mora sadržavati ne samo zaglavlje neposredno koje slijedi, već i Sve naredni naslovi. Dodatna polja se povećavaju kako se približavate početku zip datoteke. Budući da je maksimalna dužina polja 2 16 −1 bajta, možete citirati samo do 1808 lokalnih zaglavlja datoteke (ili 1170 u Zip64) uz pretpostavku imena (u slučaju DEFLATE možete koristiti dodatno polje da citirate prvo (najkraće) zaglavlja lokalnih datoteka, a zatim se prebacite na citiranje DEFLATE za ostatak). Drugi problem je da da bi se uskladila sa internom strukturom podataka dodatnog polja, 16-bitna oznaka za tip (APPNOTE.TXT, odeljak 4.5.2) mora biti izabrana pre podataka o citatu. Želimo odabrati oznaku tipa koja će uzrokovati da parseri ignorišu citirane podatke umjesto da ih pokušavaju protumačiti kao smislene metapodatke. Zip parseri moraju zanemariti tagove nepoznatog tipa, tako da možemo birati oznake nasumično, ali postoji rizik da će neka oznaka u budućnosti narušiti kompatibilnost dizajna.

Prethodni dijagram ilustruje mogućnost korišćenja dodatnih polja u bzip2, sa i bez Zip64. Oba grafa imaju tačku prekida u kojoj rast ide od kvadratnog do linearnog. Bez Zip64, ovo se dešava kada se dostigne maksimalna veličina nekomprimovane datoteke (2 32 -2 bajta); tada se može povećati samo broj datoteka, a ne njihova veličina. Grafikon se u potpunosti završava kada broj datoteka dostigne 1809, u kom trenutku nam ponestane prostora u dodatnom polju za citiranje dodatnih naslova. Sa Zip64, prekid se događa na 1171 fajlu, nakon čega se može povećati samo veličina datoteka, a ne broj datoteka. Dodatno polje pomaže i kod DEFLATE, ali razlika je toliko mala da se vizualno ne primjećuje. Povećava omjer kompresije zbsm.zip za 1,2%; zblg.zip za 0,019%; i zbxl.zip za 0,0025%.

Diskusija

U svom radu na ovoj temi, Pletz i kolege koriste preklapanje datoteka kako bi stvorili gotovo samoreplicirajuću zip arhivu. Preklapanje fajlova je ranije (slajd 47) predložio Ginvael Coldwind.

Dizajnirali smo zip bombu koja se preklapa sa citatima imajući na umu kompatibilnost, brojne razlike u implementaciji, od kojih su neke prikazane u tabeli ispod. Rezultirajuća konstrukcija je kompatibilna sa zip parserima, koji rade na uobičajeni način, tj. prvo provjeravaju centralni direktorij i koriste ga kao indeks datoteke. Među njima je jedinstveni zip parser iz Naila, koji se automatski generiše iz formalne gramatike. Međutim, dizajn je nekompatibilan sa "stream" parserima, koji analiziraju zip datoteku s kraja na kraj u jednom prolazu bez prethodnog čitanja centralnog direktorija. Po svojoj prirodi, parseri toka ne dozvoljavaju preklapanje datoteka bilo koje vrste. Najvjerovatnije će izdvojiti samo prvi fajl. Osim toga, mogu čak i izbaciti grešku, kao što je slučaj sa

U članku se spominje 9 slojeva zip datoteka, tako da to nije samo gomila nula. Zašto 9, zašto 10 fajlova u svakom?

Prvo, članak na Wikipediji trenutno kaže 5 slojeva od 16 datoteka. Nisam siguran gdje se događa nedosljednost, ali to nije sve što je relevantno. Pravo pitanje je zašto uopšte koristiti gnežđenje.

DEFLATE, jedina podržana metoda kompresije za zip datoteke*, ima maksimalan omjer kompresije od 1032. Ovo se može postići asimptotski za bilo koji ponavljajući niz od 1-3 bajta. Bez obzira što radite sa zip datotekom, sve dok se koristi samo sa DEFLATE, veličina dekomprimirane datoteke neće biti veća od 1032 puta veličine originalne zip datoteke.

Stoga se moraju koristiti ugniježđene zip datoteke da bi se postigli zaista nečuveni omjeri kompresije. Ako imate 2 sloja kompresije, maksimalni omjer je 1032^2 = 1065024. Za 3, to je 1099104768 i tako dalje. Za 5 slojeva koji se koriste u 42.zip, teoretski maksimalni omjer kompresije je 1170572956434432. Kao što vidite, stvarna veličina 42.zip je daleko od ovog nivoa. Dio toga su troškovi zip formata, a dio je to što ih jednostavno nije briga.

Kad bih morao nagađati, rekao bih da je 42.zip nastao stvaranjem velikog praznog fajla i njegovim kopiranjem i kopiranjem više puta. Ne postoji način da se pomaknu ograničenja formata ili maksimizira kompresija ili bilo šta - oni su samo nasumično odabrali 16 kopija po sloju. Poenta je bila da se stvori veliki teret bez mnogo napora.

Bilješka. Drugi formati kompresije, kao što je bzip2, nude mnogo, mnogo, mnogo veće maksimalne omjere kompresije. Međutim, većina zip parsera ih ne prihvaća.

P.S. Moguće je kreirati zip fajl koji će raspakovati svoju kopiju (quine). Možete napraviti i onaj koji raspakuje više kopija. Dakle, ako rekurzivno dekomprimirate datoteku zauvijek, maksimalna moguća veličina je beskonačna. Jedino ograničenje je da se može povećati samo za 1032 na svakoj iteraciji.

P.P.S. Vrijednost 1032 pretpostavlja da se podaci datoteke u zip-u ne preklapaju. Jedna karakteristika zip formata datoteke je da ima centralni direktorij koji navodi datoteke u arhivi i pomake podataka datoteke. Ako kreirate više unosa u datotekama koji upućuju na iste podatke, možete postići mnogo veće omjere kompresije čak i bez ugniježđenja, ali će takav zip fajl vjerovatno biti odbijen od strane parsera.

reci prijateljima