Załóżmy, że sprawdzam kod, który wysyłają kandydaci, aby udowodnić swoje umiejętności. Oczywiście nie chcę uruchamiać plików wykonywalnych, które wysyłają. Nie tak wyraźnie, wolałbym nie uruchamiać wyniku kompilacji ich kodu (na przykład Java pozwala ukryć kod wykonywalny w komentarzach ).
A co ze skompilowaniem ich kodu? Chcę ostrzeżenia kompilatora, jeśli w ogóle, ale jeśli ich kod zawiera sprytne sekwencje znaków, które wykorzystują mój kompilator, a mój kompilator zagraża mojej maszynie?
Gdy szukam „luk w kompilatorze” w Google, trafienia dotyczą optymalizacji kompilatora i emisji kodu oraz tego, czy emitowany kod jest tak bezpieczny, jak powinien być oryginalny kod źródłowy.
Czy kompilatory są zwykle sprawdzane, aby upewnić się, że nie narażą komputera użytkownika na kompilację jakiegoś sprytnego fragmentu kodu? Jak bezpieczne jest skompilowanie fragmentu kodu od nieznajomego?
źródło
Odpowiedzi:
To zależy.
Ten plik makefile może usunąć katalog domowy:
Więc jeśli potrzebujesz użyć narzędzia (takiego jak cmake lub makefile system), to nie jest bezpieczne. To zależy tylko od tego, jak złośliwy jest program kodujący.
Z drugiej strony, kompilatory są programowane przez ludzi, dlatego dostały błędy. Może więc być może możliwe, że ktoś znajdzie sposób na wykonanie złośliwego kodu podczas kompilacji.
Zgodnie z sugestiami w komentarzach, jeśli chcesz mieć pewność, że na komputerze nie są robione żadne śmieszne rzeczy, użyj maszyny wirtualnej.
źródło
Jestem pewien, że gdzieś w branży są sprytni faceci, którzy już stworzyli taki hack dla określonego języka i wersji kompilatora. Moim ulubionym miejscem do szukania czegoś takiego byłby prawdopodobnie Międzynarodowy Konkurs Obfuscated C - (nie wiem, czy jest coś porównywalnego dla Javy). Jednak w rzeczywistości, jak wysoko uważasz ryzyko, zakładam, że
wnioskodawca robi na tobie prawdopodobne wrażenie, że naprawdę chce pracy w Twojej firmie (a nie procesu)
facet nie wie, ile przeglądu jest zrobione u ciebie
on / ona nie wie, z której dokładnie wersji kompilatora korzystasz
on / ona nie wie, czy korzystasz ze środowiska wirtualnego czy kompilatora online, tylko dla bezpieczeństwa
nie akceptujesz programów, które są zbyt duże, aby mogły zostać skutecznie sprawdzone
nie kompilujesz niczego, co wydaje ci się podejrzane
nie ma wielu ludzi na świecie, którzy faktycznie wiedzą, jak technicznie wykonać takie zadanie (a samo googlowanie nie da ci „szybkiego ref” lub samouczka na ten temat, jak już się przekonałeś).
Więc chociaż kompilacja nie jest „całkowicie bezpieczna” w teorii, IMHO w rzeczywistości ryzyko jest bardzo niskie, że twój „kompilator zostanie pwned”.
źródło
Musimy wyróżnić kilka przypadków:
Makefile
, abuild.xml
,configure
skrypt powłoki itp. Technicznie nie jest to spowodowane kompilacją kodu atakującego, ale raczej skonfigurowaniem środowiska kompilacji.# 4. i # 5. spowoduje co najwyżej odmowę usługi. Praktycznie, kompilatory C ++ i Scala ograniczyć ilość rekursji można zrobić tak, że nie jest to rzeczywiście możliwe, aby napisać nieskończoną pętlę. W Scali jest to tylko ograniczenie implementacyjne, ale w C ++ jest to wyraźnie dozwolone przez specyfikację.
# 2. technicznie jest poza zakresem pytania, ponieważ chodziło o kompilację kodu, który go nie uruchamia (OTOH, istnieje głębokie filozoficzne pytanie: jeśli sprawdzanie typu programu Haskell może wykonać dowolne obliczenia Turinga, czy to kompilacja czy uruchomienie programu?)
# 1. mało prawdopodobnym jest. Z jednej strony kompilatory produkcyjne są bardzo złożone, więc prawdopodobieństwo błędów jest wysokie. Z drugiej strony są one rygorystycznie testowane, w końcu wdzięczne obchodzenie się z źle sformułowanymi danymi wejściowymi jest częścią opisu zadania kompilatora. Nawet jeśli nie zostaną przetestowane, i tak zostaną zbombardowane źle sformułowanym kodem ... wystarczy spojrzeć na pytania StackOverflow, aby zobaczyć przykłady tego, co śmieciowi ludzie rzucają na swoje kompilatory!
Pozostaje nam 3. Niektóre kompilatory mogą ograniczyć rodzaj dostępu, jaki kod czasu kompilacji ma do systemu, ale w niektórych przypadkach użycia pełny dostęp jest nieunikniony. Na przykład dostawcy typów F # mają na celu „fałszowanie” typów syntetycznych dla danych, których system typów nie pasuje do F #, aby można było wchodzić w interakcje z, powiedzmy, usługą internetową, która ma schemat WSDL w silnie typowanym typie moda. Jednak w tym celu dostawca typów musi mieć dostęp do zasobu schematu WSDL w systemie plików lub w Internecie, więc musi mieć dostęp do systemu plików i dostępu do sieci.
Czy to jest bezpieczne? Technicznie nie. Czy to ryzykowne? Nie całkiem.
źródło
Kompilacja kodu nie powinna wiązać się z żadnym ryzykiem . W teorii nie może być błąd w kompilator, że sprytny haker może skorzystać z dźwięków, ale jest bardzo mało prawdopodobne.
Pamiętaj, że budynek może być niebezpieczny. Na przykład w C # „zdarzenie kompilacji” pozwala określić dowolne wiersze poleceń do wykonania przed i po kompilacji, co jest oczywiście niebezpieczne i o wiele łatwiejsze w użyciu, niż stwierdzenie przepełnienia bufora w kodzie kompilatora.
źródło
Zamiast spekulować, naprawdę zastanawiałem się, czy nie przeprowadzić badań na ten temat przed udzieleniem odpowiedzi, przechodząc do najbardziej autorytatywnego zasobu, jaki mogłem wymyślić ( Szczegóły CVE ). Ta kompleksowa lista publicznie ujawnionych exploitów bezpieczeństwa jest prawdopodobnie najlepsza, co można zrobić, aby ocenić poziomy zagrożenia różnych rodzajów oprogramowania.
Oczywiście nie poświęciłem czasu na przeczytanie wszystkich dostępnych materiałów, ale wybrałem kilka „podstawowych” kompilatorów, IDE i edytorów tekstu, aby opracować przykładową ocenę zagrożenia. Jeśli poważnie myślisz o uruchomieniu jakiegokolwiek oprogramowania, powinieneś przynajmniej zobaczyć, jakie są zagrożenia. Należy również pamiętać, że starsze oprogramowanie jest na ogół bardziej szkodliwe niż nowsze oprogramowanie, więc uruchomienie najnowszej wersji tego, co uruchomisz, jest idealne.
Po pierwsze, możemy spojrzeć na różne edytory tekstu. Wydaje się, że najlepsi redaktorzy są najprostsi. Vi, jeśli używasz powłoki Linuxa lub Notatnika, jeśli korzystasz z systemu Windows. Coś bez możliwości formatowania, bez parsowania, po prostu przeglądanie danych i automatyczne kończenie parsowania, jeśli pojedynczy znak znajduje się poza bieżącym schematem kodowania. Nawet Notepad ++ miał garść słabych punktów. Unikaj skomplikowanych elementów podczas przeglądania niezaufanych plików.
Po drugie, możemy spojrzeć na IDE. Jeśli zdecydujesz się otworzyć plik w środowisku IDE, powinieneś pamiętać, że niektóre środowiska IDE zgłosiły błędy. Najwyraźniej Visual Studio ma exploity dostępne za pośrednictwem mechanizmu rozszerzeń, więc otwarcie rozwiązania może być problematyczne. Unikanie IDE pozwala uniknąć całej klasy problemów między tobą a niezaufanym kodem. Trzymanie się VI wydaje się znacznie bezpieczniejsze.
Po trzecie, możemy spojrzeć na rzeczywiste kompilatory. Przeglądałem kilka, w tym Adobe, Microsoft, Java i GNU C / C ++, i stwierdziłem, że ogólnie mówiąc, kompilowanie kodu (a nawet budowanie , przy założeniu braku niestandardowego pliku make) jest względnie bezpieczne, ale każdy z tych kompilatorów działa lub robi zawierają exploity bezpieczeństwa, które mogą wynikać z faktycznego uruchamiania skompilowanych plików binarnych. Innymi słowy, nie mogliby przejąć twojego systemu po prostu przez kompilację, ale mogliby uruchomić kod.
Podsumowując, zakładając, że metoda dostarczania nie przejęła już systemu (np. Włamano się do klienta poczty e-mail lub dysk USB, na którym się pojawił, został zainfekowany ...), odczyt kodu źródłowego i kompilacja kodu źródłowego jest prawdopodobnie bezpieczna . Badając konkretne oprogramowanie, możesz uczynić go jeszcze bezpieczniejszym, powiedzmy, sprawdzanie poprawności pliku znajduje się na właściwej stronie kodowej itp. Uruchamianie kodu powinno odbywać się tylko na sprzęcie, na którym ci po prostu nie zależy. Nie maszyna wirtualna, ale cały fizycznie inny komputer bez dostępu do sieci i bez poufnych plików lub urządzeń zewnętrznych. Nawet jeśli uważasz, że rozumiesz kod, proste badania pokazują, że nawet kompilatory mają błędy, które mogą pozwolić exploitowi przepełnienia bufora ukryć się od tyłu i wykonać dowolny kod, ale tylko jeśli zdecydujesz sięuruchom lub debuguj program. Rzeczywista kompilacja powinna być bezpieczna.
źródło
Zacznę od „przeglądu ich kodu”. Dlaczego istnieje potrzeba uruchomienia kodu?
Oprócz tego istnieje wiele kompilatorów online, w których można po prostu wstawić kod, skompilować i / lub uruchomić. Możesz to zrobić: kompiluje się w tym i tym kompilatorze internetowym.
Oto przykład strony z kompilatorami online: Kompilatory online
Kod do przeglądu rozmowy kwalifikacyjnej nie powinien być tak duży, abyś nie rozumiał, co się dzieje.
źródło
Zasadniczo są one zbyt złożone i często pisane przy użyciu języków, w których udowodnienie tej właściwości nie jest praktyczne.
Być może nie z tą konkretną intencją, ale pojęcie kompilatorów testujących fuzz jest co najmniej znane ( LLVM może teraz sam testować fuzz ). Testy przeznaczone do wejścia catch że wywala kompilator powodu błędów kompilator zwykle również włączyć się do eksploatacji wady.
Oczywiście musisz sprawdzić, czy konkretny kompilator, który Cię interesuje, jest testowany czy testowany pod kątem fuzzów, aby znaleźć potencjalne awarie i czy znalezione błędy zostały naprawione. Ogólna zasada jest taka, że jeśli zdarzają się awarie gorsze niż wyjątki braku pamięci, to bez dalszego badania szczegółów należy rozważyć poważną możliwość wykorzystania ich w exploitach.
Niestety, jak długi jest kawałek sznurka. Zasadniczo wiadomość e-mail może wykorzystywać klienta poczty lub kod źródłowy może wykorzystywać edytor tekstu lub cppcheck, zanim dotrze nawet do kompilatora. Sugestia Sebastiana w komentarzach do korzystania z kompilatora online jest całkiem dobra, ale oczywiście kod musi być w formie zaakceptowanej przez kompilator.
Każdy język lub kompilator z funkcjami do wykonywania ogólnego kodu jest wysoce podejrzane. Szablony C ++ są funkcjonalnie kompletne, ale nie mają (zamierzonego) dostępu do systemu, więc ich ryzyko jest stosunkowo niewielkie. BЈовић wspomina
make
o bardzo wysokim ryzyku (ponieważ wykonuje kod nieznajomego, po prostu kod jest napisany wmake
języku, a nie w C ++). Jeśli kompilator będzie działałsystem
, jesteś na tej samej łodzi. Kiedyś pracowałem z asemblerem, który, jeśli dobrze pamiętam, mógł wykonać dowolne wykonanie kodu w czasie kompilacji. Był przeznaczony do obliczania tablic przeglądowych, ale nie sądzę, aby cokolwiek przeszkadzało w wykonywaniu wywołań systemowych.W praktyce , jeśli kod wydaje mi się OK i myślę, że go rozumiem, wówczas uważam, że skompilowanie go jest wyjątkowo niskie, znacznie mniejsze ryzyko niż powiedzenie „przeglądanie Internetu przy zablokowanej przeglądarce”. Rutynowo robię bardziej ryzykowne rzeczy na moim komputerze ogólnego przeznaczenia, ale wielu z nich nie zrobiłbym np. W laboratorium wirusów lub na krytycznym serwerze. Jeśli kod wygląda śmiesznie lub najwyraźniej jest zaciemniony, nie mogę ryzykować jego kompilacji, ponieważ oprócz ryzyka może zawierać exploita ukrytego w nieczytelnych śmieciach, jest to kod śmieci. Zły kod jest trudny, ale możliwy. Niedoceniany kod, który atakuje maszynę za pośrednictwem exploita kompilatora, musi zawierać nietrywialny plik wykonywalny, więc jest to niezwykle trudne.
Jeśli chcesz przyjrzeć się temu bliżej, spróbuj zapytać ludzi, którzy hostują kompilatory online. Jeśli nie zostało im to zrobione (wtedy, gdy nie zwracasz uwagi na NSA lub odpowiednik), możesz rozsądnie założyć, że nie zostanie ci to zrobione. Włożyli trochę wysiłku w uruchomienie swojego kompilatora w odpowiednim piaskownicy, co może być większym wysiłkiem, niż jesteś skłonny przejść, ale mogą przynajmniej być w stanie powiedzieć, jak często piaskownica oszczędza im problemów.
źródło
Chociaż jest to ogólnie problem, myślę, że problem nie istnieje z powodu konfiguracji.
Wnioskodawca przesłał ci kod źródłowy. Jak to się stało?
Oczywiście są tylko trzy możliwości:
Około 2) i 3)
Głównym ryzykiem jest rozróżnienie między 2) a 3). Szanse są duże, że jeśli cokolwiek pisał to warto przyjrzeć , to jest coś, co można albo dostać kodu źródłowego w Internecie (z „neutralnego” źródła), a może nawet znać już, czy jest to coś, co rzeczywiście don nie chcę patrzeć, ponieważ naruszyłbyś własność intelektualną konkurenta (byłego pracodawcy). To ostatnie oznaczałoby, że i tak nie chciałbyś zatrudnić tej osoby.
Jeśli możesz uzyskać źródło online, zrób to. Jeśli możesz zweryfikować udział wnioskodawcy w znanym oprogramowaniu (w tym oprogramowaniu chronionym prawem autorskim) według jego nazwiska gdzieś w napisach, zrób to.
W każdym innym przypadku po prostu zignoruj to, co ci wysłał. To nie jest warte patrzenia, nielegalne lub wysokiego ryzyka.
Około 1)
Skarżący wysłał ci coś, ponieważ powierzyłeś mu zadanie. Jeśli masz jakieś kompetencje (które, jak zakładam, masz!), To w przypadku typowego zadania programistycznego (... które sam wybrałeś!) Będziesz w stanie stwierdzić, czy jest to prawdopodobne rozwiązanie, które wygląda tak, jakby mogło zadziałać patrząc na kod źródłowy przez mniej niż 30 sekund (bardziej prawdopodobne 10 sekund).
Jeśli nie możesz powiedzieć, że program prawdopodobnie zadziała (lub co w ogóle robi) w ciągu 30 sekund, ten, który napisał go, nie jest osobą, którą chcesz zatrudnić, zatrzymaj się. Chcesz ludzi, którzy piszą kod, który inni ludzie mogą zrozumieć i zachować. Nie chcesz kogoś, kto próbuje się na ciebie sprytnie, ani kogoś, kto regularnie wygrywa zaciemniony konkurs C. Nie ma nawet znaczenia, czy program działa. Gdy tylko inna osoba nie zrozumie kodu, nigdy nie „działa”.
Jeśli program wygląda tak, jakby prawdopodobnie działał, ale znajdziesz coś, co wygląda „dziwnie” (powiedzmy, sekwencje specjalne Unicode Java, dosłowne ciągi znaków C ++, rzeczy, które wyglądają jak trójwymiarowe, cokolwiek), traktuj to zadanie jako „niepowodzenie”, przesuń do następnego wnioskodawcy. Nie jest konieczne dołączanie czegokolwiek podobnego do 99% wszystkich programów (i oczywiście nie w twoim zadaniu - mam nadzieję). Jeśli więc znajdziesz coś „dziwnego”, kandydat nie jest kimś, kogo chciałbyś zatrudnić.
Jeśli kod przejdzie tę pierwszą segregację, możesz poświęcić kolejne 2-3 minuty na dokładniejsze jej przeanalizowanie. Jeśli nadal jesteś zadowolony z tego, co zobaczysz później, możesz uruchomić go przez analizator statyczny i skompilować na maszynie wirtualnej na wysokim poziomie ostrzegania.
Powinno to wywołać problemy, które mogłeś przeoczyć podczas czytania źródła (takie jak wywołanie niezdefiniowanego zachowania lub zawężenie konwersji).
Kompilacja pokaże przede wszystkim, czy kandydat ma niezbędną staranność i dbałość o szczegóły, a nie tyle, czy ma umiejętności programowania. Podobnie jak w przypadku poprawnego wpisania nazwy pracodawcy w aplikacji i sprawdzania pisowni CV przed jej przekazaniem, najlepszą praktyką jest upewnienie się, że każdy przekazany kod źródłowy kompiluje się bez błędów (i najlepiej bez ostrzeżeń). Jeśli ktoś tego nie zrobi, nie chcesz go zatrudnić.
Ryzyko wystąpienia złych rzeczy w tym momencie (wykorzystanie kompilatora i wyłamanie się z maszyny wirtualnej) jest znikome, biorąc pod uwagę, jak już wykonałeś kontrolę wiarygodności kodu. Nie zdarzy się.
źródło
Jeśli ta możliwość Cię martwi, weź starszą maszynę (czy większość z nas nie ma przy sobie kilku), zainstaluj aktualną wersję Linuksa i kompilatora & c, skopiuj do niego kod źródłowy, odłącz kabel sieciowy (lub wyłącz Wi-Fi ) i wykonaj kompilacje. Jeśli wydarzy się coś paskudnego, * nie wpłynie to na nic innego.
W przypadku złośliwego oprogramowania w pliku Makefile uruchom je z flagą -n (IIRC, RTMF), aby zobaczyć, co zrobi bez faktycznego wykonania tego.
* Chyba że twój programista zakodował szkodliwe oprogramowanie tak, aby czekało na ponowne połączenie, ale w takim przypadku a) wyczyść maszynę; oraz b) przesłać CV faceta do NSA, ponieważ zmarnował się w świecie komercyjnym :-)
źródło
Najważniejsze jest to, że nie ma ryzyka. Ryzyko jest dość małe, jak zauważają inne odpowiedzi, ale istnieje ryzyko. Oznacza to, że musisz zadać dwa pytania:
Drugie jest to, co postawiłeś tutaj w tym pytaniu, ale jest to niewłaściwe ukierunkowanie w tym konkretnym przypadku. Odpowiedź na ograniczenie ryzyka jest jasna i łatwo dostępna: nie kompiluj kodu na swoim komputerze . Istnieją dwa oczywiste sposoby kompilacji bez użycia komputera:
Te sposoby ograniczania ryzyka są tak oczywiste, tanie i łatwo dostępne, że nie warto poświęcać dużo czasu na analizowanie wielkości tego ryzyka. Po prostu zrób jeden z nich i gotowe.
źródło
Program Visual Studio faktycznie ostrzega, jeśli otworzysz projekt z niezaufanego miejsca (np. Pobranego lub udziału sieciowego).
Przykładem tego może być projekt WPF: można odwoływać się do klas .NET z XAML oraz zapewnić IntelliSense, VS ładuje i wykonuje klasy, do których się odwołuje, w czasie projektowania.
Oznacza to, że osoba atakująca może upuścić złośliwą bibliotekę .dll do katalogu bin, zastąpić kod źródłowy kodem innym niż złośliwy, a podczas projektowania biblioteka DLL jest wykonywana. Po pierwszej kompilacji zniknął każdy ślad złośliwego pliku binarnego.
Więc nawet jeśli cały dostarczony kod jest „czysty”, kompilator jest wolny od błędów i, oczywiście, nigdy nie wykonujesz ręcznie żadnego dostarczonego pliku .EXE, złośliwy kod może być nadal wykonywany w tle. (Aby zabezpieczyć się przed tym konkretnym atakiem, możesz po prostu upewnić się, że NIE ma plików binarnych w drzewie katalogów przed otwarciem rozwiązania. VS poprosi cię o zbudowanie rozwiązania przed udostępnieniem IntelliSense w czasie projektowania.)
Podobne wektory prawdopodobnie istnieją w innych językach / systemach operacyjnych.
źródło
Odczytywanie kodu źródłowego: całkowicie bezpieczne. Kompilowanie kodu źródłowego: całkowicie bezpieczne. Wykonywanie skompilowanych plików binarnych: cóż ... to zależy.
Kompilacja to tylko komputer odczytujący kod źródłowy i zapisujący jego ekwiwalent w formie binarnej. Po kompilacji masz tylko 2 dokumenty: jeden czytelny dla człowieka, a drugi czytelny dla komputera. O ile komputer nie przeczyta (tzn. Uruchomi) drugiego dokumentu, nic się nie wydarzy.
źródło
mvn package
może pobierać rzeczy i wykonywać zadania z dodatkowymi wtyczkami, o których możesz nie wiedzieć. Jestem pewien, że to samo może dotyczyć innych systemów kompilacji.Myślę, że martwisz się jednym z dwóch smaków:
Niektórzy sugerowali maszyny wirtualne lub stare systemy, ale ja oferuję znacznie łatwiejsze rozwiązanie: Kompiluj jako inny użytkownik z ograniczonymi / różnymi uprawnieniami . Znacznie łatwiejsze niż skonfigurowanie maszyny wirtualnej lub dedykowanego komputera.
Jeśli jest mało prawdopodobne, że twój system zostanie zainfekowany przez exploity czasu kompilacji, przywróć z kopii zapasowych (masz je, prawda?).
źródło