To pytanie dotyczące bomb zipowych w naturalny sposób doprowadziło mnie do strony Wikipedii na ten temat. W artykule wymieniono przykład pliku zip o rozmiarze 45,1 kb, który jest dekompresowany do 1,3 eksabajta.
Jakie są zasady / techniki, które zostałyby zastosowane do stworzenia takiego pliku w pierwszej kolejności? Właściwie nie chcę tego robić, bardziej interesuje mnie uproszczone wyjaśnienie „jak to działa”.
ps
W artykule wspomniano o 9 warstwach plików ZIP, więc nie jest to prosty przypadek spakowania kilku zer. Dlaczego 9, dlaczego po 10 plików w każdym?
algorithm
compression
rozdymka tygrysia
źródło
źródło
Odpowiedzi:
Cytując ze strony Wikipedii:
Wszystko, czego potrzebujesz, to jeden plik 1,3 GB pełen zer, skompresuj go do pliku ZIP, zrób 10 kopii, zapakuj je do pliku ZIP i powtórz ten proces 9 razy.
W ten sposób otrzymujesz plik, który po całkowitym zdekompresowaniu tworzy absurdalną ilość danych bez konieczności rozpoczynania od tej ilości.
Ponadto zagnieżdżone archiwa znacznie utrudniają programom takim jak skanery antywirusowe (główny cel tych „bomb”) sprytne działanie i odmawianie rozpakowywania archiwów, które są „zbyt duże”, ponieważ do ostatniego poziomu łączna ilość danych jest nie tak bardzo, nie „widzisz”, jak duże są pliki na najniższym poziomie, dopóki nie osiągniesz tego poziomu, a każdy pojedynczy plik nie jest „zbyt duży” - problem stanowi jedynie ogromna liczba.
źródło
Utwórz plik o wielkości 1,3 eksabajta z zerami.
Kliknij prawym przyciskiem myszy> Wyślij do folderu skompresowanego (spakowanego).
źródło
W systemie Linux można to łatwo zrobić za pomocą następującego polecenia:
dd if=/dev/zero bs=1024 count=10000 | zip zipbomb.zip -
Zastąp liczbę liczbą KB, które chcesz skompresować. Powyższy przykład tworzy bombę zipową 10 MiB (w ogóle nie jest to bomba, ale pokazuje proces).
NIE potrzebujesz miejsca na dysku twardym do przechowywania wszystkich nieskompresowanych danych.
źródło
Poniżej dotyczy systemu Windows:
Z dowodu koncepcji Security Focus (NSFW!), Jest to plik ZIP z 16 folderami, każdy z 16 folderami, który działa w ten sposób (42 to nazwa pliku zip):
Prawdopodobnie mylę się z tą liczbą, ale daje ona 4 ^ 16 (4 294 967 296) katalogów. Ponieważ każdy katalog potrzebuje miejsca na alokację N bajtów, ostatecznie jest ogromny. Plik dll na końcu ma 0 bajtów.
Rozpakowanie samego pierwszego katalogu
\42\lib 0\book 0\chapter 0\doc 0\0.dll
daje 4 GB miejsca alokacyjnego.źródło
Poważna odpowiedź:
(Zasadniczo) Kompresja polega na wykrywaniu powtarzających się wzorców, więc plik zip zawierałby dane reprezentujące coś podobnego
Bardzo krótki plik zip, ale ogromny po rozwinięciu.
źródło
Aby utworzyć taki plik w praktycznym ustawieniu (tj. Bez tworzenia pliku 1,3 eksabajta na ogromnym dysku twardym), prawdopodobnie musiałbyś nauczyć się formatu pliku na poziomie binarnym i napisać coś, co przekłada się na to, jak wyglądałby żądany plik, po kompresja.
źródło
Po pierwsze, artykuł na Wikipedii mówi obecnie o 5 warstwach po 16 plików. Nie jestem pewien, skąd bierze się ta rozbieżność, ale nie jest to aż tak istotne. Prawdziwe pytanie brzmi: po co w ogóle używać zagnieżdżania.
DEFLATE, jedyna powszechnie obsługiwana metoda kompresji plików zip *, ma maksymalny współczynnik kompresji 1032. Można to osiągnąć asymptotycznie dla dowolnej powtarzającej się sekwencji 1-3 bajtów. Bez względu na to, co zrobisz z plikiem zip, o ile używa on tylko DEFLATE, rozmiar po rozpakowaniu będzie co najwyżej 1032 razy większy od oryginalnego pliku zip.
Dlatego konieczne jest użycie zagnieżdżonych plików ZIP, aby osiągnąć naprawdę skandaliczne współczynniki kompresji. Jeśli masz 2 warstwy kompresji, maksymalny współczynnik wynosi 1032 ^ 2 = 1065024. Dla 3 jest to 1099104768 i tak dalej. Dla 5 warstw użytych w pliku 42.zip teoretyczny maksymalny współczynnik kompresji wynosi 1170572956434432. Jak widać, rzeczywisty 42.zip jest daleki od tego poziomu. Po części jest to narzut związany z formatem zip, a po części po prostu ich to nie obchodzi.
Gdybym miał zgadywać, powiedziałbym, że plik 42.zip został utworzony po prostu przez utworzenie dużego pustego pliku i wielokrotne spakowanie go i skopiowanie. Nie ma próby przekroczenia granic formatu, maksymalizacji kompresji czy czegokolwiek - po prostu wybrali arbitralnie 16 kopii na warstwę. Chodziło o to, aby bez większego wysiłku stworzyć dużą ładowność.
Uwaga: inne formaty kompresji, takie jak bzip2, oferują znacznie, dużo, dużo większe maksymalne współczynniki kompresji. Jednak większość parserów zip ich nie akceptuje.
PS Możliwe jest utworzenie pliku zip, który rozpakuje się do własnej kopii (quine). Możesz także utworzyć taki, który rozpakuje się do wielu kopii samego siebie. Dlatego, jeśli rekurencyjnie rozpakujesz plik na zawsze, maksymalny możliwy rozmiar jest nieskończony. Jedynym ograniczeniem jest to, że może wzrosnąć maksymalnie o 1032 w każdej iteracji.
PPS Rysunek 1032 zakłada, że dane pliku w pliku zip są rozłączne. Jedną z dziwactw formatu pliku zip jest to, że ma on katalog centralny, który zawiera listę plików w archiwum i przesunięcia do danych pliku. Jeśli utworzysz wiele pozycji pliku wskazujących na te same dane, możesz osiągnąć znacznie wyższe współczynniki kompresji nawet bez zagnieżdżania, ale taki plik zip zostanie prawdopodobnie odrzucony przez parsery.
źródło
Dobrym sposobem na utworzenie bomby zip (lub gzbomb) jest znajomość docelowego formatu binarnego. W przeciwnym razie, nawet jeśli używasz pliku strumieniowego (na przykład używając
/dev/zero
), nadal będziesz ograniczony mocą obliczeniową potrzebną do skompresowania strumienia.Ładny przykład bomby gzip: http://selenic.com/googolplex.gz57 (w pliku jest wiadomość osadzona po kilku poziomach kompresji, co powoduje powstanie ogromnych plików)
Baw się dobrze, znajdując tę wiadomość :)
źródło
Być może na Uniksie mógłbyś przelać pewną liczbę zer bezpośrednio do programu zip lub coś w tym stylu? Nie wiem jednak wystarczająco dużo o Uniksie, aby wyjaśnić, jak byś to zrobił. Poza tym potrzebowałbyś źródła zer i umieść je w suwaku, który czyta ze stdin lub coś takiego ...
źródło
Wszystkie algorytmy kompresji plików opierają się na entropii kompresowanych informacji. Teoretycznie możesz skompresować strumień zer lub jedynek i jeśli jest wystarczająco długi, kompresuje się bardzo dobrze.
To część teorii. Część praktyczna została już wskazana przez innych.
źródło
Najnowsze (po 1995 r.) Algorytmy kompresji, takie jak bz2, lzma (7-zip) i rar, zapewniają spektakularną kompresję monotonnych plików, a pojedyncza warstwa kompresji wystarcza, aby zawinąć zbyt dużą zawartość do rozsądnego rozmiaru.
Innym podejściem mogłoby być utworzenie rzadkiego pliku o ekstremalnych rozmiarach (eksabajtach), a następnie skompresowanie go czymś przyziemnym, który rozumie rzadkie pliki (np. Tar), teraz, jeśli egzaminator przesyła plik strumieniowo, egzaminator będzie musiał odczytać wszystkie istniejące zera tylko w celu dopełnienia między rzeczywistą zawartością pliku, jeśli egzaminator zapisze go na dysku, jednak zajmie bardzo mało miejsca (przy założeniu dobrze zachowanego niezarchiwizowanego pliku i nowoczesnego systemu plików).
źródło
Spróbował tego. wyjściowy plik zip miał rozmiar 84 KB.
Kroki, które wykonałem do tej pory:
chociaż nie wiem, jak wyjaśnić część, w której kompresja pliku zip o zmienionej nazwie nadal kompresuje go do mniejszego rozmiaru, ale działa. Może po prostu brakuje mi terminów technicznych.
źródło
Sezon 3, odcinek 7 Doliny Krzemowej przywiódł mnie tutaj. Kroki do wygenerowania bomby zip byłyby.
1.zip
.n
(powiedzmy 10) kopii tego pliku i dodaj te 10 plików do skompresowanego archiwum (powiedzmy2.zip
).k
kilka razy.W przypadku implementacji Pythona sprawdź to .
źródło
Nie wiem, czy ZIP używa kodowania Run Length Encoding, ale gdyby tak było, taki skompresowany plik zawierałby mały fragment danych i bardzo dużą wartość run-length. Wartość run-length określa, ile razy mały fragment danych jest powtarzany. Jeśli masz bardzo dużą wartość, wynikowe dane są proporcjonalnie duże.
źródło