Czy hack kompilatora Kena Thompsona nadal stanowi zagrożenie?

156

Ken Thompson Hack (1984)

Ken Thompson przedstawił metodę uszkodzenia binarnego kompilatora (i innego skompilowanego oprogramowania, takiego jak skrypt logowania w systemie * nix) w 1984 roku. Byłem ciekawy, czy współczesna kompilacja usunęła tę lukę w zabezpieczeniach, czy nie.

Krótki opis:

Ponownie napisz kod kompilatora, aby zawierał 2 błędy:

  • Podczas kompilacji własnego pliku binarnego kompilator musi skompilować te wady
  • Kompilując jakiś inny wybrany kod (funkcja logowania) musi skompilować dowolny dowolny backdoor

W ten sposób kompilator działa normalnie - kiedy kompiluje skrypt logowania lub podobny, może stworzyć backdoor bezpieczeństwa, a kiedy kompiluje swoje nowsze wersje w przyszłości, zachowuje poprzednie wady - a wady będą istnieć tylko w kompilatorze binarne, więc są niezwykle trudne do wykrycia.

Pytania:

W sieci nie mogłem znaleźć odpowiedzi na te pytania:

  • Jak to się ma do kompilacji just-in-time?
  • Czy funkcje takie jak program obsługujący logowanie w systemie * nix są kompilowane po uruchomieniu?
  • Czy wciąż jest to uzasadnione zagrożenie, czy też od 1984 r. Pojawiły się zmiany w bezpieczeństwie kompilacji, które uniemożliwiają poważny problem?
  • Czy to wpływa na wszystkie języki?

Dlaczego chcę wiedzieć?

Natknąłem się na to podczas odrabiania lekcji i wydawało mi się to interesujące, ale brakuje mi tła, aby zrozumieć w konkretny sposób, czy jest to bieżący problem, czy rozwiązany problem.

Materiał referencyjny

svick
źródło
6
Strategia Diverse Double Compiling jest dość niezawodnym sposobem wykrywania obecności kompilatora RoTT.
dmckee
3
Wyobrażam sobie, że NSA włożyło wiele pracy w tego rodzaju atak.
Paul M

Odpowiedzi:

110

Ten hack należy rozumieć w kontekście. Został opublikowany w czasie i kulturze, w której Unix działający na różnego rodzaju sprzęcie był dominującym systemem.

Co sprawiło, że atak był tak straszny, że kompilator C był centralny kawałek oprogramowania dla tych systemów. Niemal wszystko w systemie przeszło przez kompilator podczas jego pierwszej instalacji (dystrybucje binarne były rzadkie ze względu na heterogeniczny sprzęt). Wszyscy cały czas kompilowali. Ludzie regularnie sprawdzali kod źródłowy (często musieli wprowadzać poprawki, aby kompilować go w ogóle), więc kompilowanie backdoora kompilatora wydawało się rodzajem scenariusza „idealnego przestępstwa”, w którym nie można Cię złapać.

W dzisiejszych czasach sprzęt jest znacznie bardziej kompatybilny, a zatem kompilatory odgrywają znacznie mniejszą rolę w codziennej pracy systemu. Zaatakowany kompilator nie jest już najbardziej przerażającym scenariuszem - rootkity i skompromitowany BIOS są jeszcze trudniejsze do wykrycia i pozbycia się.

Michael Borgwardt
źródło
27
Lub, ponieważ większość ludzi nie kompiluje niczego ze źródła (powiedzmy w systemie Windows), wystarczy twój przeciętny trojan :) (Zgadzam się, że skompromitowany kompilator to zdecydowanie przesada)
Andres F.,
16
@ArjunShankar: Niewolny, zastrzeżony kompilator binarny nie potrzebuje i nie może mieć tego backdoora. Ten backdoor dotyczy tylko kompilatorów, które kompilujesz sam z kodu źródłowego.
ruakh
12
Z wyjątkiem pulpitu, Unix i wszystkie jego warianty nadal są dominującym systemem operacyjnym.
Rob
7
@ruakh: może nie rozumiem twojego nacisku na „to”, ale zdarza się, że się nie zgadzam. Jeśli ten backdoor został wprowadzony w firmie, która akurat jest właścicielem niewolnego, zastrzeżonego kompilatora i używa tego kompilatora do kompilacji nowych wersji tego samego kompilatora, ten backdoor miałby znacznie gorszy wpływ niż w pierwotnym scenariuszu. Potrzebujesz tylko jednego wektora ataku, aby zainfekować wszystkich.
orithena
8
Wyobraź sobie, że ktoś kompromituje serwer kompilacji Ubuntu i zastępuje kompilator bez zmiany źródła. Może minąć trochę czasu, zanim się to dowie, i do tego czasu obrazy ubuntu będą wypychane do ludzi na całym świecie z wbudowanym skompromitowanym kompilatorem (wraz ze skompromitowanymi zestawami logowania lub czymś innym). Myślę, że nadal jest to całkowicie uzasadniona obawa.
Jimmy Hoffa
74

Celem tego przemówienia nie było podkreślenie podatności, którą należy usunąć, ani nawet zaproponowanie teoretycznej podatności, o której musimy wiedzieć.

Chodziło o to, że jeśli chodzi o bezpieczeństwo, nie chcielibyśmy nikomu ufać, ale niestety jest to niemożliwe. Ty zawsze musisz zaufać komuś (stąd tytuł: „Refleksje ufność Trust”)


Nawet jeśli jesteś typem paranoika, który szyfruje dysk twardy komputera i odmawia uruchomienia oprogramowania, którego sam nie skompilowałeś, nadal musisz zaufać swojemu systemowi operacyjnemu. Nawet jeśli sam skompilujesz system operacyjny, nadal musisz zaufać używanemu kompilatorowi. Nawet jeśli skompilujesz własny kompilator, nadal musisz zaufać temu kompilatorowi! I nie wspominając nawet o producentach sprzętu!

Po prostu nie można uciec od ufania nikomu . Właśnie o to starał się przejść.

BlueRaja - Danny Pflughoeft
źródło
2
Jeśli ktoś ma kompilator typu open source, którego zachowanie nie zależy od żadnego zachowania zdefiniowanego lub nieokreślonego w implementacji, kompiluje go przy użyciu różnych niezależnie opracowanych kompilatorów (zaufanych lub nie), a następnie kompiluje jeden program przy użyciu wszystkich różnych skompilowanych wersji ten open-source, każdy kompilator powinien generować dokładnie to samo wyjście. Jeśli tak, sugerowałoby to, że jedynym sposobem, w jaki trojan mógłby być w jednym, byłby, gdyby był identyczny we wszystkich. Wydaje się to raczej mało prawdopodobne. Jeden z moich problemów z dużą ilością .net ...
supercat
9
@ superupat: Wygląda na to, że brakuje ci sensu. Mówisz, że hack przedstawiony przez Kena Thompsona można obejść. Mówię, że ten konkretny hack, który wybrał, nie ma znaczenia; był to tylko przykład, aby wykazać, że jego najważniejszym punktem jest to, że zawsze trzeba komuś ufać . Dlatego to pytanie jest nieco bez znaczenia - całkowicie tęskni za lasem za drzewami.
BlueRaja - Danny Pflughoeft
9
@ superuper: Jest bardzo mało prawdopodobne, że różne kompilatory wygenerowałyby ten sam kod bajtowy dla każdego nietrywialnego programu z powodu różnych decyzji projektowych, optymalizacji itp. Rodzi to pytanie - skąd byś wiedział, że pliki binarne są identyczne?
Ankit Soni
1
@AnkitSoni: Moja odpowiedź jest bardziej szczegółowa. Przesyłanie odpowiednio napisanego kompilatora / linkera typu open source przez różne kompilatory powinno dać różne pliki wykonywalne, które będą zachowywać się identycznie . Jeśli pliki wykonywalne faktycznie zachowują się identycznie, wygenerują takie same dane wyjściowe, jeśli zostanie przez nie przepuszczony kod kompilatora / linkera typu open source. Aby porównać pliki, można skopiować je na dyskietkę i porównać je za pomocą starego komputera.
supercat
2
Czy część tej rozmowy nie oznaczałaby tylko, że w przypadku testowanych rzeczy pliki binarne / sprzęt działały zgodnie z oczekiwaniami? Wciąż może być w tym coś, czego nie testowałeś i czego nie jesteś świadomy.
Bart Silverstrim
53

Nie

Atak, jak pierwotnie opisano, nigdy nie stanowił zagrożenia. Chociaż teoretycznie kompilator mógłby to zrobić, faktyczne przeprowadzenie ataku wymagałoby zaprogramowania kompilatora

  • Rozpoznaj, kiedy kompilowany kod źródłowy pochodzi z kompilatora, oraz
  • Dowiedz się, jak zmodyfikować dowolny kod źródłowy, aby wstawić do niego włamanie.

Wymaga to zrozumienia, jak działa kompilator na podstawie kodu źródłowego, aby mógł go modyfikować bez uszkodzenia.

Wyobraź sobie na przykład, że format łączenia przechowuje długości danych lub przesunięcia skompilowanego kodu maszynowego gdzieś w pliku wykonywalnym. Kompilator musiałby sam ustalić, które z nich wymagają aktualizacji i gdzie, przy wstawianiu ładunku exploita. Kolejne wersje kompilatora (wersja nieszkodliwa) mogą dowolnie zmieniać ten format, więc kod exploita musiałby skutecznie rozumieć te pojęcia.

Jest to samodzielne programowanie na wysokim poziomie, trudny problem sztucznej inteligencji (ostatnio sprawdziłem, że stan techniki generuje kod, który jest praktycznie określony przez jego typy). Spójrz: niewielu ludzi może to zrobić; musisz nauczyć się języka programowania i najpierw zrozumieć bazę kodu.

Nawet jeśli problem sztucznej inteligencji zostanie rozwiązany, ludzie zauważą, że kompilacja ich małego kompilatora daje plik binarny z ogromną biblioteką sztucznej inteligencji.

Analogiczny atak: zaufanie ładowania początkowego

Jednak uogólnienie ataku jest istotne. Podstawową kwestią jest to, że Twój łańcuch zaufania musi gdzieś zacząć, a w wielu domenach jego pochodzenie może obalić cały łańcuch w trudny do wykrycia sposób.

Przykład, który można łatwo wyciągnąć w prawdziwym życiu

Twój system operacyjny, powiedzmy Ubuntu Linux, zapewnia bezpieczeństwo (integralność) aktualizacji poprzez sprawdzanie pobranych pakietów aktualizacji względem klucza podpisu repozytorium (przy użyciu kryptografii klucza publicznego). Ale to gwarantuje autentyczność aktualizacji tylko wtedy, gdy możesz udowodnić, że klucz do podpisywania jest własnością legalnego źródła.

Skąd masz klucz do podpisu? Po pierwszym pobraniu dystrybucji systemu operacyjnego.

Musisz ufać, że źródło twojego łańcucha zaufania, ten klucz do podpisywania, nie jest złe.

Każdy, kto może MITM połączyć się z Internetem między tobą a serwerem pobierania Ubuntu - może to być twój dostawca usług internetowych, rząd kontrolujący dostęp do Internetu (np. Chiny) lub dostawca hostingu Ubuntu - mógł przejąć ten proces:

  • Wykryj, że pobierasz obraz dysku CD Ubuntu. Jest to proste: sprawdź, czy żądanie trafia do dowolnego z (publicznie wymienionych) serwerów lustrzanych Ubuntu i prosi o nazwę pliku obrazu ISO.
  • Podaj żądanie z własnego serwera, dając ci obraz CD zawierający klucz publiczny i lokalizację repozytorium zamiast Ubuntu.

Odtąd będziesz otrzymywać swoje aktualizacje bezpiecznie z serwera atakującego. Aktualizacje działają jako root, więc atakujący ma pełną kontrolę.

Możesz zapobiec atakowi, upewniając się, że oryginał jest autentyczny. Wymaga to jednak sprawdzenia poprawności pobranego obrazu płyty CD za pomocą skrótu ( niewiele osób to robi ) - a sam skrót musi zostać bezpiecznie pobrany, np. Przez HTTPS. A jeśli osoba atakująca może dodać certyfikat na komputerze (często w środowisku korporacyjnym) lub kontrolować urząd certyfikacji (np. Chiny), nawet HTTPS nie zapewnia ochrony.

Ślimak mechaniczny
źródło
47
To nieprawda. Kompilator musi jedynie określić, kiedy kompiluje bardzo konkretny plik źródłowy z własnego kodu źródłowego z bardzo konkretną zawartością, a nie kiedy kompiluje dowolny kompilator !!!
Kaz
14
@Kaz - W pewnym momencie modyfikacje kompilatora lub programu logowania nadbudowy mogą doprowadzić do tego, że pokonają one kompilator-program rozpoznający / backdoor kompilatora / backdoora, a kolejne iteracje spowodują utratę backdoora. Jest to analogiczne do losowej mutacji biologicznej zapewniającej odporność na niektóre choroby.
Russell Borogove
12
Pierwsza połowa twojej odpowiedzi ma problem, który opisuje Kaz, ale druga połowa jest tak dobra, że ​​i tak daję +1!
ruakh
7
Kompilator zła, który rozpoznaje tylko własne źródło, jest łatwy do zbudowania, ale w praktyce względnie bezwartościowy - niewiele osób, które mają już plik binarny tego kompilatora, użyłby go do odtworzenia tego pliku binarnego. Aby atak był skuteczny przez dłuższy czas, kompilator potrzebowałby więcej inteligencji, aby załatać nowsze wersje własnego źródła, napotykając w ten sposób problemy opisane w snswer.
user281377,
5
Rozpoznawanie konkretnego kompilatora może być dość ogólne i raczej nie złamie się w obliczu nowej wersji. Weźmy na przykład gcc - wiele wierszy kodu w gcc jest bardzo starych i niewiele się zmieniło. Proste rzeczy, takie jak nazwa, prawie nigdy się nie zmieniają. Zanim rozpoznanie nie powiedzie się, prawdopodobnie wstrzyknie kod. W rzeczywistości oba te problemy są w dużej mierze teoretyczne - w praktyce autor szkodliwego oprogramowania nie miałby problemów z utrzymaniem (powolnego) tempa rozwoju kompilatora.
Eamon Nerbonne
25

Po pierwsze, mój ulubiony opis tego hacka to Strange Loops .

Ten konkretny hack mógłby z pewnością (*) zostać dzisiaj wykonany w jednym z głównych projektów systemów operacyjnych typu open source, szczególnie Linux, * BSD i tym podobne. Spodziewałbym się, że zadziała prawie identycznie. Na przykład pobierasz kopię FreeBSD, która ma wyzyskiwany kompilator do modyfikacji openssh. Odtąd problem będzie kontynuowany przy każdej aktualizacji openssh lub kompilatora według źródła. Zakładając, że atakujący wykorzystał system użyty do spakowania FreeBSD w pierwszej kolejności (prawdopodobnie, ponieważ sam obraz jest uszkodzony, lub atakujący jest w rzeczywistości programem pakującym), to za każdym razem, gdy system odbudowuje pliki binarne FreeBSD, ponownie pojawi się problem. Istnieje wiele sposobów niepowodzenia tego ataku, ale nie różnią się one zasadniczo od tego, w jaki sposób atak Kena mógł się nie udać (**). Świat naprawdę niewiele się zmienił.

Oczywiście podobne ataki mogą być równie łatwo (lub łatwiej) wstrzyknięte przez ich właścicieli do systemów takich jak Java, iOS SDK, Windows lub inny system. Niektóre rodzaje błędów bezpieczeństwa można nawet wprowadzić w sprzęcie (szczególnie osłabienie generowania liczb losowych).

(*) Ale przez „z pewnością” mam na myśli „w zasadzie”. Czy należy oczekiwać, że tego rodzaju dziura istnieje w jakimś konkretnym systemie? Nie. Uważam to za mało prawdopodobne z różnych praktycznych powodów. Z biegiem czasu, wraz ze zmianami i kodem, wzrasta prawdopodobieństwo, że tego rodzaju włamanie spowoduje dziwne błędy. A to zwiększa prawdopodobieństwo, że zostanie to odkryte. Mniej pomysłowe backdoory wymagałyby konspiracji do utrzymania. Oczywiście wiemy na pewno, że backdoory „zgodne z prawem” zostały zainstalowane w różnych systemach telekomunikacyjnych i sieciowych, więc w wielu przypadkach taki skomplikowany hack nie jest konieczny. Włamanie jest instalowane jawnie.

Tak więc zawsze głęboka obrona.

(**) Zakładając, że atak Kena kiedykolwiek istniał. Właśnie przedyskutował, jak można to zrobić. Nie powiedział, że faktycznie to zrobił, o ile wiem.

Rob Napier
źródło
W odniesieniu do drugiego przypisu Ken powiedział „buduj i nie rozpowszechniaj”.
8bittree
15

Czy to wpływa na wszystkie języki?

Ten atak dotyczy przede wszystkim języków, które same się hostują. To są języki, w których kompilator jest napisany w samym języku. C, Squeak Smalltalk i interpreter PyPy Python będą miały na to wpływ. Perl, JavaScript i interpreter języka Python CPython nie.

Jak to się ma do kompilacji just-in-time?

Nie bardzo. Jest to kompilator, który pozwala na ukrywanie włamań. Nie znam żadnych samodzielnych kompilatorów JIT. (Może LLVM?)

Czy funkcje takie jak program obsługujący logowanie w systemie * nix są kompilowane po uruchomieniu?

Zazwyczaj nie. Ale pytanie nie brzmi, kiedy jest kompilowane, ale według jakiego kompilatora . Jeśli program logowania zostanie skompilowany przez skażony kompilator, zostanie on skażony. Jeśli zostanie skompilowany przez czysty kompilator, będzie czysty.

Czy wciąż jest to uzasadnione zagrożenie, czy też od 1984 r. Pojawiły się zmiany w bezpieczeństwie kompilacji, które uniemożliwiają poważny problem?

To wciąż teoretyczne zagrożenie, ale mało prawdopodobne.

Jedną z rzeczy, które możesz zrobić, aby to złagodzić, jest użycie wielu kompilatorów. Na przykład kompilator LLVM, który sam jest kompilowany przez GCC, nie przejdzie tylnymi drzwiami. Podobnie GCC skompilowana przez LLVM nie przejdzie tylnymi drzwiami. Jeśli więc martwisz się tego rodzaju atakiem, możesz skompilować kompilator z innym rodzajem kompilatora. Oznacza to, że zły haker (u twojego dostawcy systemu operacyjnego?) Będzie musiał skazić oba kompilatory, aby się rozpoznali; Znacznie trudniejszy problem.

Sean McMillan
źródło
Twój ostatni akapit nie jest, ściśle mówiąc, prawdziwy. Teoretycznie kod może wykryć kompilację kompilatora i odpowiednio wypisać tylne drzwi. Jest to oczywiście niepraktyczne w prawdziwym świecie, ale nic nie stoi na przeszkodzie. Ale pierwotny pomysł nie dotyczył prawdziwych praktycznych zagrożeń, ale raczej lekcję zaufania.
Steven Burnap,
Uczciwy punkt. W końcu hack przenosi backdoora do logowania i mod do kompilatora, więc może przenosić mod do innego kompilatora. Ale staje się to coraz bardziej mało prawdopodobne.
Sean McMillan
Kompilacja w samą porę może być gratką. Jeśli jakiś kod ma pewną lukę tylko wtedy, gdy określony fragment jest skompilowany w JIT, może pozostać niezauważony. (po prostu czysto thoery)
GameDeveloper
12

Istnieje teoretyczna szansa na to. Istnieje jednak sposób sprawdzenia, czy jakiś kompilator (z dostępnym kodem źródłowym) nie został naruszony, dzięki podwójnej kompilacji Diverse Davida A. Wheelera .

Zasadniczo użyj zarówno podejrzanego kompilatora, jak i innego niezależnie opracowanego kompilatora, aby skompilować źródło podejrzanego kompilatora. To daje SC SC SC T . Teraz skompiluj podejrzane źródło, używając obu tych plików binarnych. Jeśli wynikowe pliki binarne są identyczne (z wyjątkiem wielu rzeczy, które mogą się legalnie różnić, takich jak różne znaczniki czasu), podejrzany kompilator nie nadużywał zaufania.

Vatine
źródło
Albo ten, albo zaufany kompilator nie jest tak godny zaufania, jak myślał użytkownik. Jednak w przypadku dwóch niezależnych implementacji języka prawdopodobieństwo, że zawierają one ten sam backdoor, jest znikome.
Damian Yerrick
Albo narzędzie porównywania, którego używasz do ich porównywania, również zostało przejęte;)
iCodeSometime
@kennycoc Jednak napisanie narzędzia porównywania „czy te dwa pliki nie są identyczne” nie jest, biorąc pod uwagę wszystko, takie trudne (jak w przypadku odniesienia do syscall, powinno to być możliwe w ciągu 2-16 godzin w binarnym kodzie maszynowym).
Vatine
3

Jako konkretny atak stanowi tak samo duże zagrożenie, jak nigdy dotąd, co w zasadzie nie stanowi żadnego zagrożenia.

Jak to się ma do kompilacji just-in-time?

Nie jestem pewien, co przez to rozumiesz. Czy JITter jest na to odporny? Nie. Czy to jest bardziej wrażliwe? Nie całkiem. Jako programista Twoja aplikacja jest bardziej podatna na ataki po prostu dlatego, że nie możesz sprawdzić, czy nie zostało to zrobione. Zauważ, że twoja jeszcze nierozwinięta aplikacja jest w zasadzie odporna na tę i wszystkie praktyczne odmiany, musisz tylko martwić się o kompilator, który jest nowszy niż twój kod.

Czy funkcje takie jak program obsługujący logowanie w systemie * nix są kompilowane po uruchomieniu?

To nie jest tak naprawdę istotne.

Czy wciąż jest to uzasadnione zagrożenie, czy też od 1984 r. Pojawiły się zmiany w bezpieczeństwie kompilacji, które uniemożliwiają poważny problem?

Nie ma prawdziwego bezpieczeństwa kompilacji i nie może być. To był właśnie sens jego rozmowy, że w pewnym momencie musisz komuś zaufać.

Czy to wpływa na wszystkie języki?

Tak. Zasadniczo w pewnym momencie instrukcje muszą zostać przekształcone w coś, co komputer wykonuje, a tłumaczenie może być wykonane niepoprawnie.

jmoreno
źródło
-2

David Wheeler ma dobry artykuł: http://www.dwheeler.com/trusting-trust/

Ja bardziej martwię się atakami sprzętowymi. Myślę, że potrzebujemy łańcucha narzędzi do projektowania w całości VLSI z kodem źródłowym FLOSS, który sami możemy modyfikować i kompilować, co pozwala nam budować mikroprocesor, w którym narzędzia nie wstawiają tylnych drzwi. Narzędzia powinny również pozwolić nam zrozumieć cel każdego tranzystora w układzie. Następnie moglibyśmy otworzyć próbkę gotowych układów i sprawdzić je pod mikroskopem, upewniając się, że mają ten sam zespół obwodów, co narzędzia, które według nich powinny mieć.

Paweł
źródło
3
-1, większość odpowiedzi nie zawiera odpowiedzi na pytanie.
-3

Systemy, w których użytkownicy końcowi mają dostęp do kodu źródłowego, są tymi, dla których musiałbyś ukryć ten rodzaj ataku. W dzisiejszym świecie byłyby to systemy typu open source. Problem polega na tym, że chociaż istnieje zależność od jednego kompilatora dla wszystkich systemów Linux, atak musiałby dostać się na serwery kompilacji dla wszystkich głównych dystrybucji Linuksa. Ponieważ nie pobierają one plików binarnych kompilatora bezpośrednio dla każdej wersji kompilatora, źródło ataku musiałoby znajdować się na ich serwerach kompilacji w co najmniej jednej poprzedniej wersji kompilatora. Zarówno ta, jak i pierwsza wersja kompilatora pobranego jako plik binarny musiałaby zostać zagrożona.

Dale Gulledge
źródło
2
Twoja odpowiedź rysuje się na powierzchni pytania, ale tak naprawdę nie odnosi się do pytania.
-4

Jeśli ktoś ma kod źródłowy dla kompilatora / systemu kompilacji, którego dane wyjściowe nie powinny zależeć od niczego poza zawartością dostarczonych plików źródłowych, i jeśli ktoś ma kilka innych kompilatorów i wie, że nie wszystkie zawierają ten sam hack kompilatora, można upewnij się, że otrzymujesz plik wykonywalny, który nie zależy od niczego innego niż kod źródłowy.

Załóżmy, że ktoś ma kod źródłowy pakietu kompilatora / linkera (powiedzmy Groucho Suite) napisany w taki sposób, że jego wynik nie będzie zależał od żadnych nieokreślonych zachowań, ani od niczego innego niż zawartość wejściowych plików źródłowych, a jeden kompiluje / łączy ten kod w różnych niezależnie produkowanych kompilatorach / pakietach łączących (np. Harpo Suite, Chico Suite i Zeppo Suite), uzyskując dla każdego inny zestaw ekwiwalentów (nazywaj je G-Harpo, G-Chico i G-Zeppo). Nie byłoby niespodzianką, że te pliki wykonywalne zawierają różne sekwencje instrukcji, ale powinny być funkcjonalnie identyczne. Jednak udowodnienie, że są one funkcjonalnie identyczne we wszystkich przypadkach, prawdopodobnie stanowiłoby trudny problem.

Na szczęście taki dowód nie będzie konieczny, jeśli użyje się wynikowych plików wykonywalnych tylko w jednym celu: ponownej kompilacji pakietu Groucho. Jeśli jeden kompiluje pakiet Groucho za pomocą G-Harpo (uzyskując GG-Harpo), G-Chico (GG-Chico) i G-Zeppo (GG-Zeppo), wówczas wszystkie trzy wynikowe pliki, GG-Harpo, GG-Chico i GG-Zeppo, wszystkie bajty po bajcie powinny być identyczne. Jeśli pliki się zgadzają, oznaczałoby to, że każdy „wirus kompilatora”, który istnieje w jednym z nich, musi istnieć identycznie we wszystkich (ponieważ wszystkie trzy pliki są identyczne bajt po bajcie, nie ma możliwości, aby ich zachowanie mogło się różnić droga).

W zależności od wieku i pochodzenia innych kompilatorów może być możliwe zapewnienie, że taki wirus nie będzie w nich istniał. Na przykład, jeśli ktoś użyje antycznego Macintosha, aby nakarmić kompilator napisany od zera w 2007 r. Za pomocą wersji MPW napisanej w latach 80., kompilatory z lat 80. nie będą wiedziały, gdzie wstawić wirusa w kompilatorze z 2007 r. Możliwe, że dziś kompilator może wykonać wystarczająco wymyślną analizę kodu, aby to rozgryźć, ale poziom obliczeń wymagany do takiej analizy znacznie przekroczyłby poziom obliczeń wymagany do zwykłego skompilowania kodu i nie mógłby nie zostać niezauważony na rynku, gdzie szybkość kompilacji była głównym punktem sprzedaży.

Zakładam, że jeśli ktoś pracuje z narzędziami do kompilacji, w których bajty w pliku wykonywalnym, który ma zostać wygenerowany, nie powinno w żaden sposób zależeć od niczego poza zawartością przesłanych plików źródłowych, możliwe jest uzyskanie względnie dobrej odporności na Thompson wirus typu. Niestety z jakiegoś powodu niedeterminizm w kompilacji wydaje się być uważany za normalny w niektórych środowiskach. Rozumiem, że w systemie wieloprocesorowym kompilator może działać szybciej, jeśli pewne aspekty generowania kodu mogą się różnić w zależności od tego, który z dwóch wątków kończy pracę jako pierwszy.

Z drugiej strony nie jestem pewien, czy widzę jakiś powód, dla którego kompilatory / konsolidatory nie powinny zapewniać trybu „kanonicznego wyjścia”, w którym dane wyjściowe zależą tylko od plików źródłowych i „daty kompilacji”, która może zostać zastąpiona przez użytkownika . Nawet jeśli kompilacja kodu w takim trybie zajęła dwa razy więcej czasu niż normalna kompilacja, sugerowałbym, że istotną wartością byłoby odtworzenie „kompilacji wydania”, bajt po bajcie, całkowicie z materiałów źródłowych, nawet jeśli oznaczałoby to, że kompilacje wersji zajęłyby dłużej niż „normalne kompilacje”.

supercat
źródło
2
-1. Nie rozumiem, w jaki sposób twoja odpowiedź odnosi się do podstawowych aspektów pytania.
@ GlenH7: Wiele starszych narzędzi do kompilacji konsekwentnie generowałoby identyczne bity, gdy otrzymywałby identyczne bity [poza takimi rzeczami jak CZAS , który można by dostosować, aby zgłosić „oficjalny” czas kompilacji]. Za pomocą takich narzędzi można całkiem dobrze chronić się przed wirusami kompilatora. Fakt, że niektóre popularne platformy programistyczne nie pozwalają na „deterministycznie” kompilujący kod, oznacza, że ​​techniki, które mogłyby chronić przed wirusami w starszych narzędziach, nie mogą być skutecznie stosowane w nowszych.
supercat
Próbowałeś tego? 1. Poprowadź swoją pracę magisterską. 2. Użyj krótszych akapitów. 3. Wyraźniej określ różnicę między „identycznym funkcjonalnie” (wynik pierwszego etapu) a „bitowym identycznym” (wynikiem drugiego etapu), być może z listą wszystkich wyprodukowanych plików binarnych kompilatora i ich wzajemnych relacji. 4. Cytuj artykuł Davida A. Wheelera.
Damian Yerrick