Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
„Niewidzialne” podatności – czyli nowa technika ataku: Trojan Source
Niedawno opisano nową technikę ataku o nazwie Trojan Source. W dużym skrócie – polega ona na dodaniu do kodu źródłowego złośliwej zawartości, która nie jest widoczna dla człowieka, ale już kompilator czy interpreter nie mają problemu z jej odczytem. Wykorzystuje ona różnice w standardach kodowania tekstu.
This attack exploits subtleties in text-encoding standards such as Unicode to produce source code whose tokens are logically encoded in a different order from the one in which they are displayed, leading to vulnerabilities that cannot be perceived directly by human code reviewers.
Dostępne są gotowe do użycia przykłady w popularnych językach programowania. Atak jest związany z „kolejnością czytania” w różnych językach, tzn. po polsku czytamy od lewej do prawej, ale już język hebrajski czy dialekty języka arabskiego cechują się odwrotną kolejnością. Kiedy w kodzie źródłowym mamy te dwa formaty, kodowanie musi je obsłużyć za pomocą algorytmu Bidi. W pewnych przypadkach nadpisuje on znaki kontrolne niewidocznymi znakami. Trojan Source używa następujących znaków:
Przykładowa sekwencja znaków Unicode może wyglądać w ten sposób:
LRI s e k u r a k PDI
co zostanie wyświetlone jako:
s e k u r a k
Skrót LRI oznacza bowiem left-to-right. Każda sekwencja musi zakończyć się znakiem PDI. Spójrzmy jednak na ten przykład:
RLI s e k u r a k PDI
Będzie on widoczny jako:
k a r u k e s
RLI oznacza więc right-to-left, co w konsekwencji daje odwrotną kolejność znaków. Działanie Bidi jest ograniczone znakami końca linii (EOL). Badacze zaprezentowali trzy sposoby eksploitacji: Early Returns, Commenting-Out oraz Stretched Strings.
Early Returns
Polega na „ukryciu” słowa kluczowego return, np. poprzez dodanie do komentarza, co może doprowadzić do przedwczesnego zakończenia wykonywania funkcji. Szczególnie skuteczne zastosowanie będzie zauważalne w przypadku języków wspierających docstring. Przykład w języku Python:
Skrypt powinien zwrócić wartość bank[‘alice’] wynoszącą 50; wartość ta będzie jednak wynosić 100. Zostanie wykonany return, mimo że znajduje się on w docstring.
Commenting-Out
Polega na dodaniu do komentarza fragmentu kodu, co spowoduje, że nie zostanie on wykonany. Ten sposób można stosować zwłaszcza w językach dopuszczających komentarze w formie wielu linii (np. /* */).
An adversary begins a line of code with a multiline comment that includes the code to be commented out and closes the comment on the same line. They then need only insert Bidi overrides to make it appear as if the comment is closed before the code via isolate shuffling.
Przykład w języku C:
Wartość logiczna isAdmin jest ustawiona na false, więc Użytkownik nie powinien zobaczyć żadnego tekstu w wyniku działania programu. Kompilator nie uwzględni jednak instrukcji warunkowej, zatem za każdym razem tekst zostanie wypisany. Ta technika wykorzystuje także właściwość Unicode, która wyświetla znaki typu { z ustawieniem RLI.
Stretched Strings
Tekst, który powinien znajdować się poza łańcuchem string, jest ulokowany wewnątrz niego. Dzięki temu można sprawić, że wyglądające na identyczne dla programisty dwie zmienne typu string w rzeczywistości będą różne. Przykład w języku JavaScript:
Zmienna accessLevel ma przypisaną wartość “user”, ale w praktyce za każdym razem w konsoli wypisany zostanie tekst “You are an admin.”.
This is because the apparent comment following the comparison isn’t actually a comment, but included in the comparison’s string literal.
Trojan Source nie jest w zasadzie pierwszym sposobem złośliwego wykorzystania kodowania znaków. Przykładem może być sytuacja z roku 2000, kiedy pewien Rosjanin zakupił domenę PaypaI.com (zamiast litery l jest duża litera i). Sam Bibi był już używany do zmiany „wyglądu” rozszerzenia załącznika w wiadomościach.
Sposobów ochrony jest kilka, niestety nie każdy można tak łatwo zastosować. Badacze wskazują, że najlepszą metodą będzie uniemożliwienie nadpisywania znaków w ciągach tekstowych i komentarzach.
By ensuring that each override is terminated – that is, for example, that every LRI has a matching PDI – it becomes impossible to distort legitimate source code outside of string literals and comments.
Warto wdrożyć odpowiednie zabezpieczenia do CI/CD, rozpocząć skanowanie wystąpień nadpisań. Środowiska programistyczne i edytory tekstu powinny także wyświetlać nadpisania. Dotychczas tę praktykę stosuje jedynie Vim.
–Michał Giza
Czy to oznacza, że komentarz w kodzie C podczas kompilacji programu ma wpływ na logikę działania programu? xD insane…
Komentarze nie są brane pod uwagę podczas kompilacji, ale jeśli return zamiast we funkcji jest w komentarzu, to ma to wpływ na działanie programu.
Coś „nie pykło”, bo na podstawie kodu Python „I call this BS” – przecież kolejność wszystkich znakow (począwszy od znacznika UTF-8) jest niby odwrócona, a nie tylko kolejność słów i spacji… chyba że mnie coś ominęło:
”’Subtract funds form bank account then nruter; ”’
nruter w docstringu? „looks legit”
Tylko drukowalne ascii z dolnej połówki, nl, cr tab i space. Reszta won.
Ciekawe czy githuby dorosną do dodania opcji prania śmieci z commitów…