06.12.2015 | 18:05

Adam Haertle

Historia z piekła rodem czyli najgorszy koszmar programisty

Poprawianie cudzego kodu samo z siebie wydaje się już być wystarczającym koszmarem. Co jednak powiedzieć o sytuacji, kiedy przejrzany i poprawiony kod robi rzeczy, których zdecydowanie nie są w nim zaprogramowane?

W serwisie Quora furorę robi pewna odpowiedź na pytanie Jaki jest najgorszy koszmar programisty. Choć historia w niej opisana sprawia wrażenie wręcz nierealnej, to renoma jej autora sugeruje, że wydarzyła się naprawdę. Przeczytajcie.

To tylko drobne poprawki

Mick Stute, autor opowieści, został kiedyś poproszony przez pewnego psychologa o naprawienie programu autorstwa byłego studenta naukowca. Program służył do wczytania danych z bazy, zadania użytkownikowi 50 pytań i wyświetlenia wyników. Pozornie działał prawidłowo, jednak w trakcie wyświetlania pytań na ekranie pojawiały się momentami różne dziwne słowa, których być tam nie powinno. Z pozoru banalne zadanie usunięcia tego elementu z kodu okazało się prowadzić do wielodniowej batalii. Walka prowadzona była na komputerze 3B2 na początku lat 80. XX wieku.

Zestaw z 3B2 w roli głównej

Zestaw z 3B2 w roli głównej

Mick podjął się zadania. Już pierwszy rzut oka na kod źródłowy zapowiadał problemy. Program, napisany w C, rozbity był na 15 różnych plików i każdy plik zawierał pojedynczy wiersz obejmujący +/- trzy różne funkcje. Wszystkie nazwy zmiennych były losowymi, trzyliterowymi ciągami. Mick postanowił umówić się z autorem zlecenia na stawkę godzinową i po ustaleniu warunków zasiadł do rozplątywania kodu.

Program używał biblioteki curses by ustawić na ekranie kursor w odpowiednim miejscu i wyświetlić treść pytania. Zanim jednak pojawiało się pytanie, na pół sekundy wyświetlany był rasistowski komentarz. Mick wyczyścił i uporządkował cały kod. Zlokalizował 5 miejsc, w których znajdowały się polecenia wyświetlające na ekranie zawartość pytań – w każdym z nich był zapisany fragment z dodatkowym komunikatem. Usunął niepotrzebne polecenia, skompilował kod i myślał że już skończył pracę. Program był jednak innego zdania i znowu wyświetlił rasistowskie komentarze, choć tym razem o innej treści.

Gdy Mick spojrzał na kod źródłowy lekko się załamał. Wszystko wróciło do stanu wyjściowego – trzyliterowe zmienne, 15 plików i nieczytelne długie wiersze. Niestety nie zrobił kopii zapasowej wyczyszczonego kodu, zatem musiał powtórzyć od początku całą procedurę. Tym razem przed skompilowaniem programu zrobił kilka kopii, lecz efekt był identyczny. Oprócz jego kodu – pozornie czystego, choć ciągle produkującego niewłaściwy kod wyjściowy, miał na dysku znowu kopię kodu oryginalnego. To jednak nie było problemem – problemem było ustalenie, skąd biorą się polecenia wyświetlania rasistowskich komentarzy.

Wyszukiwanie wybranego fragmentu wyświetlanego komunikatu w /usr/include nie przyniosło spodziewanych rezultatów. Drugi dzień pracy spędzony na analizie plików źródłowych dołączanych do kodu nie posunął pracy do przodu. Ciągi musiały być gdzieś zaszyfrowane. Mick postanowił zrekompilować wszystkie biblioteki. Szóstego dnia kolejna kompilacja programu w oparciu o sprawdzony kod źródłowy wszystkich elementów przyniosła identyczny efekt jak poprzednie próby – złośliwy kod znowu dodał się do pliku wynikowego.

Musimy zejść głębiej

Mick był już bliski decyzji o napisaniu całego programu od nowa, jednak postanowił się nie poddawać. Zleceniodawcę poinformował, że prace jeszcze trochę potrwają, ale nie będzie go już obciążał dodatkowymi kosztami – to była dla niego sprawa honoru. Po kolejnych sześciu dniach deasemblacji biblioteki curses Mick był znowu w punkcie wyjścia – ani śladu złośliwego kodu. Dopiero 15go dnia trwania zlecenia Micka olśniło – problemem musiał być kompilator.

Analiza kodu źródłowego kompilatora przyniosła pierwszy sukces. Mick znalazł w nim następującą sekwencję poleceń:

  • kompilator sprawdzał każdy wywołanie fopen() i weryfikował, czy wczytywany plik zawierał fragment pytań używanych w programie,
  • jeśli go znajdował, tworzył kopię zainfekowanego kodu źródłowego na dysku,
  • kompilował zainfekowany kod i zapisywał go tam, gdzie wylądować miał wynik działania kompilatora.

Z pomocą ruszył inżynier AT&T, producenta komputera, który dostarczył nietkniętą kopię kodu źródłowego kompilatora. Niestety to także nie rozwiązało problemu. Okazało się bowiem, że na feralnej maszynie kompilator był zainfekowany jeszcze innym fragmentem kodu, wykrywającym kompilowanie kompilatora. W takim przypadku zainfekowany kompilator dopisywał do kodu źródłowego swoje ukryte funkcje i dopiero wtedy się kompilował z zainfekowanego kodu. Na szczęście pomogło rozwiązanie ostateczne, czyli przeniesienie binarnej wersji czystego kompilatora z innej identycznej maszyny.

Nie był to koniec niespodzianek – na deser odkryto także że próba kompilacji /sbin/login powoduje dodanie do pliku wykonywalnego tylnej furtki umożliwiającej logowanie do systemu na konto roota za pomocą uniwersalnego hasła. Trzeba przyznać, że autor modyfikacji był nie tylko złośliwy, ale także utalentowany (pamiętajcie, że był to początek lat 80).

Wam życzymy w nadchodzącym tygodniu problemów o mniejszym poziomie złożoności. W razie kłopotów pamiętajcie o kompilatorze.

Powrót

Komentarze

  • 2015.12.06 19:14 X

    Geniusz zła.

    Odpowiedz
  • 2015.12.06 19:18 DEV

    LULZ

    Odpowiedz
  • 2015.12.06 19:38 Jacek

    Wredne, ale nie odkrywcze. Podobnie działający hack zaimplementował Ken Thompson a kodzie kompilatora, którym był kompilowany login. https://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf

    Odpowiedz
  • 2015.12.06 19:57 xxx

    1. Bądź „programistom”.
    2. Twój program musi mieć testy, do testów potrzebujesz binarnych danych porównawczych, powiedzmy z 1GB.
    3. Na share 2TB wolnego miejsca i jest podmontowany wszędzie, dla developerów też.
    4. Wczekinuj swój biarny crap do gita.
    5. Na stack overflow jest napisane, że to nie jest dobry pomysł, więc zrób reverta.
    6. Zastanawiaj się jak rozwiązać ten straszny problem.
    7. Na podmontowanym share tak bardzo 2TB wolnego miejsca.
    8. Eureka! Postaw serwer samby, z którego będziesz ściągał dane podczas kompilacji! Na podmontowanym wszędzie share tak bardzo 2TB wolnego miejsca. Skopiuj kod na share do katalogu moja_nic_nie_oznaczająca_nazwa_z_kosmosu i wystaw go przez serwer samby postawiony na jakimś kompie gdzieś tam.
    9. Napisz skryptw perlu, który ściąga dane z samby.
    10. Skrypt w perlu jest w repozytorium, które zaciągane jest jako submoduł do Twojego projektu.
    11. Twój skrypt się wywala jak masz dane już ściągnięte. Więc zrób w swoim skrypcie wywołanie komendy git clean -xf oraz git reset HEAD –hard dla pewności.

    W rezultacie masz repo, w którym jest 1GB binarnych plików, masz pliki na podmontowanym share ale dla pewności wystawiasz je za pomocą samby. Oczywiście przy okazji robisz reset repozytorium za każdym razem jak ktoś chce je skompilować.

    Ps. System buildowy wymaga, żeby kod był w odpowiedniej lokalizacji określonej na sztywno i zapisanej w kilku miejscach.

    Koniec, kurtyna.

    Odpowiedz
  • 2015.12.06 20:03 Szymon

    Jeśli pominąć fragmenty o rasistowskich komentarzach, zaciemnieniu kodu itd. to w swojej istocie – kompilator z backdoorem – jest to słynny „Ken Thompson Hack”. Myślę, że student przeczytał artykuł Thompsona „Reflections on Trusting Trust” z 1984 roku i się zainspirował.

    Odpowiedz
  • 2015.12.06 20:44 Fil

    Dawno niczego tak dobrego nie było.

    Odpowiedz
  • 2015.12.06 22:32 hm

    Jak plik może zawierać -3 różne funkcje?
    „każdy plik zawierał pojedynczy wiersz obejmujący +/- trzy różne funkcje.”

    Odpowiedz
    • 2015.12.07 14:52 mh

      Plik nie zawierał 3 różnych funkcji. Plik zawierał pojedynczy wiersz.

      Odpowiedz
      • 2015.12.08 16:40 Nick

        Chyba kwestia drobnego przekłamania – jak pisze autor w źródłowym artykule, kod był napisany tak, aby go łatwo nie rozczytać, ściśnięty do jednej linijki, rozbity na 15 plików. W każdej linijce były zapisane / ściśnięte trzy funkcje.

        Taki złośnik;)

        Odpowiedz
  • 2015.12.06 23:03 Opt

    Mysle ze to wynik mojej niewiedzy, ale od razu pomyslalem o kompilatorze :).

    Odpowiedz
  • 2015.12.07 02:36 Mickey

    Super! jak bym czytał dreszczowiec ;)

    Odpowiedz
  • 2015.12.07 11:29 as

    Rewelacyjna historia! Współczuje temu panu ;)

    Odpowiedz
  • 2015.12.08 16:52 MatM

    Ciekawostką może być fakt, że producent kompilatora dostarczył jego kod źródłowy. Z rozmów z różnymi ludźmi (znajomymi programistami czy wykładowcami akademickimi) wynika, że nie wielu z nich zdaje sobie sprawę z tego, że kiedyś oprogramowanie było otwarte na wiele lat przed FSF/RMS itp. ruchami. Ludzie przyjęli zamknięty kod źródłowy jako coś normalnego i twierdzą, że Open Source to dziwactwo lub kaprys gówniarzy z pryszczatymi buziami podczas gdy historia pokazuje coś innego.

    Odpowiedz
  • 2015.12.08 23:06 Mickie

    A wystarczyło tylko przedłużyć licencję u autora aplikacji.
    Widać wyraźnie z artykułu, że gość piszący aplikację zabezpieczył się na wypadek gdyby owoc jego pracy był wykorzystywany bez jego wiedzy. Jaki system takie zabezpieczenia. Na pewno ten co to przywłaszczył wiedział o tym doskonale, ale nie pochwalił się tym faktem.

    Odpowiedz
    • 2015.12.18 14:36 lal

      No, szkoda, że za takie „zabezpieczneia” idzie się siedzieć :)

      Odpowiedz
  • 2015.12.18 13:38 Raf

    Miał sporo wolnego czasu :)

    Odpowiedz
  • 2016.06.09 22:52 Władek

    Zastanawia mnie tylko po co ktoś zadaje sobie tyle trudu. Owszem zainfekować bankomaty i ogolić z pieniędzy… jeszcze da sie zrozumieć, potrzeba kasy itd itp. Zmalować numer w księgowości i podmienić numer konta na sobie znany aby „zarobić” w podobny sposób też jeszcze zrozumiem ale wpisywać rasistowskie hasła do zabezpieczeń… Kliniczna wręcz głupota. Ani na tym nie „zarobił” ani nie osiągnął np. celu politycznego. więc po co? Niby wykształcony gość , informatyk z dużą wiedzą a słoma z butów wystaje. Złośnika owszem jestem nawet w stanie zrozumieć ale rasistowskie hasła…(!) Słoma z butów, nic więcej. Jestem zdeklarowanym antyrasistą więc potępiam takich amatorów „zabezpieczeń” Mój znajomy mawia że : … najgorzej jak się komuś coś zdaje… I ma facet rację!

    Odpowiedz

Zostaw odpowiedź do xxx

Jeśli chcesz zwrócić uwagę na literówkę lub inny błąd techniczny, zapraszamy do formularza kontaktowego. Reagujemy równie szybko.

Historia z piekła rodem czyli najgorszy koszmar programisty

Komentarze