Przewodnik: zaciemnianie kodu, inżynieria odwrotna

Opublikowany: 2021-11-17

Dane liczbowe dotyczące zaciemniania kodu to jedno z najpopularniejszych podejść do zabezpieczania aplikacji w celu zapobiegania włamaniom do aplikacji. Jest to jedno z najczęściej sugerowanych działań AppSec przez specjalistów ds. bezpieczeństwa na całym świecie i często zapewnia bardzo minimalne wymagania bezpieczeństwa aplikacji. Strategia ta jest często wykorzystywana jako główny mechanizm obrony przed próbami włamań i chroni przed typowymi zagrożeniami, takimi jak wstrzykiwanie kodu, inżynieria wsteczna oraz manipulowanie danymi osobowymi klientów i użytkowników aplikacji.

Zaciemnianie kodu?

Praktyka zaciemniania plików wykonywalnych w taki sposób, że nie była już zrozumiała, zrozumiała lub praktyczna, jest znana jako zaciemnianie kodu. Kod źródłowy został zaciemniony do tego stopnia, że ​​jest niezrozumiały i trudny do zrozumienia dla osób trzecich, nie mówiąc już o wykonaniu. Niejasność nie ma wpływu na interfejs użytkownika końcowego lub zamierzone dane wyjściowe kodu. To tylko środek ostrożności, aby uczynić kod bezużytecznym dla potencjalnego hakera, który ma dostęp do kodu wykonywalnego oprogramowania.

Dlaczego konieczne jest zaciemnianie kodu?

Zaciemnianie kodu jest szczególnie ważne w przypadku oprogramowania typu open source, które ma znaczną wadę pod względem możliwości hakowania dla osobistych korzyści. Deweloperzy gwarantują, że własność intelektualna ich produktów jest chroniona przed zagrożeniami bezpieczeństwa, nielegalnym dostępem i wykryciem wad aplikacji, utrudniając programowi wsteczną inżynierię.

Bez względu na rodzaj zastosowanej techniki zaciemniania, takie podejście ogranicza niebezpieczny kod źródłowy i zapewnia różne poziomy bezpieczeństwa programu. Wszystkie przyczyny związane z czasem, kosztami i zasobami sprzyjają porzuceniu kodu, gdy jest on zaciemniony, ponieważ zdekompilowany kod staje się nieczytelny.

Techniki zaciemniania kodu

Zaciemnianie działa na różnych poziomach: może być zaimplementowane na poziomie struktury semantycznej/leksykalnej kodu lub na poziomie struktury danych/przepływu sterowania. Strategie maskowania różnią się również w zależności od działania na kodzie. Zasadniczo zespół ds. bezpieczeństwa określa rodzaj zaciemniania kodu, którego należy użyć we współpracy z zespołem programistów.

Należy zmienić nazwę zaciemniania.

Takie podejście pociąga za sobą mylące nazywanie zmiennych, tak aby rzeczywisty cel ich wykorzystania był sprytnie ukryty. Dekompilatorzy mają trudności ze zrozumieniem przepływu sterowania, ponieważ nazwy metod i zmiennych są zmieniane za pomocą różnych notacji i liczb. Ta metoda zaciemniania jest powszechnie używana do ukrywania kodu aplikacji platformy Java, .NET i Android. Jest to klasyfikowane jako zaciemnianie układu, ponieważ jest skierowane bezpośrednio do kodu źródłowego, aby zapewnić warstwę ochrony dla aplikacji.

Zaciemnianie danych

Ta metoda koncentruje się na strukturach danych wykorzystywanych w kodzie, uniemożliwiając hakerowi dostęp do prawdziwego celu programu. Może to pociągać za sobą zmianę sposobu przechowywania danych w pamięci przez oprogramowanie oraz sposobu przetwarzania tych danych w celu uzyskania ostatecznego wyniku. Tę procedurę można wykonać na wiele sposobów:

1. Zaciemnianie agregacji
W wyniku tego zmienia się sposób zapisywania danych w oprogramowaniu. Na przykład tablice mogą zostać podzielone na wiele podtablic, do których można się odwoływać w całym programie.

2. Zaciemnianie przechowywania danych
Ma to wpływ na sposób przechowywania danych w pamięci. Deweloperzy mogą na przykład przełączać się między przechowywaniem zmiennych lokalnych i globalnych, aby ukryć prawdziwą naturę zachowania zmiennych.

3. Uzyskiwanie zaciemniania na żądanie
Takie podejście zmienia kolejność danych bez zmiany funkcjonalności programu/fragmentu kodu. Deweloperzy osiągają to, tworząc odrębny moduł, który jest wywoływany dla każdego wystąpienia odwołania do zmiennej.

4. Szyfrowanie ciągów
Ta technika szyfruje wszystkie czytelne ciągi, w wyniku czego kod jest nieczytelny. Gdy oprogramowanie jest uruchomione, należy je odszyfrować w czasie wykonywania.

5. Zaciemnianie sterowania/przepływu kodu
Sposób, w jaki kontrola jest przekazywana z jednej części bazy kodu do drugiej, ma kluczowe znaczenie dla ustalenia celu programu. Zaciemnianie tego przepływu jest często najbardziej opłacalnym sposobem wypaczania przepływu gry. Ta strategia maskowania trzyma hakerów na dystans, utrudniając im zrozumienie, w jaki sposób i dlaczego kod podąża określoną ścieżką.

Włączenie losowych i nieoczekiwanych instrukcji, a także niepotrzebnych instrukcji przełączania wielkości liter (martwy kod), które nigdy nie zostałyby wykonane, jest jednym z najbardziej rozpowszechnionych sposobów realizacji tej strategii zaciemniania. Te twierdzenia nie mają żadnej innej funkcji poza wprawianiem w zakłopotanie docelowego hakera. W przypadku warunkowej orientacji programu ta zmiana kolejności instrukcji wykonania programu jest niezwykle przydatna.

Trwa debugowanie zaciemniania.

Informacje debugowania są często przydatne w określaniu ważnych informacji o przepływie programu i defektach poprzez dekompilację i rekompilację kodu źródłowego. Bardzo ważne jest, aby ukryć takie dane identyfikacyjne poprzez zmianę ich tożsamości, numerów wierszy lub całkowite wyłączenie dostępu do danych debugowania.

Należy zająć się zaciemnianiem.

Błędy programowania pamięci stały się powszechne w atakach, zwłaszcza w językach nie bezpiecznych dla pamięci, takich jak C i C++. Luki w zabezpieczeniach są często spowodowane błędami, takimi jak niekontrolowany dostęp do macierzy. Podejście zaciemniania adresów utrudnia inżynierię odwrotną, ponieważ wirtualne adresy kodu i dane programu są losowane za każdym razem, gdy wykonywany jest przekonwertowany kod. W rezultacie większość ataków związanych z błędami pamięci ma charakter niedeterministyczny, z bardzo małym prawdopodobieństwem powodzenia.

Spersonalizowane kodowanie

Deweloperzy stosują to podejście do szyfrowania ciągów za pomocą niestandardowego algorytmu, a następnie udostępniają funkcję dekodera w celu odzyskania oryginalnego kodu.

Argumenty przekazane w czasie wykonywania

Możliwe jest zmodyfikowanie programu tak, aby oczekiwał parametrów w czasie wykonywania. Aby zdekodować zmienne, użytkownik musi posiadać zarówno kod, jak i klucz deszyfrujący.

Aby opracować warstwową metodę ochrony aplikacji przed różnymi zagrożeniami bezpieczeństwa, zespół ds. bezpieczeństwa może zdecydować się na wdrożenie więcej niż jednej techniki w tym samym czasie.

Wniosek

Podsumowując, samo wprowadzenie w błąd jest nieskuteczne w zwalczaniu zaawansowanych problemów związanych z bezpieczeństwem. Ze względu na dostępność oprogramowania ai i umiejętności hakerów trudniej jest rozszyfrować kod, ale nie jest to niemożliwe. W rezultacie kryptografia nie jest panaceum na wszystkie problemy związane z bezpieczeństwem oprogramowania.
Zespół programistów może używać różnych podejść do zaciemniania kodu, aby zabezpieczyć swój kod w niezaufanym środowisku, w zależności od potrzeb w zakresie bezpieczeństwa, charakteru programu i testu wydajności. Należy je przeprowadzać z uwzględnieniem zalet i wad każdego podejścia. Strategia ta powinna wspierać inne inicjatywy AppSec, takie jak szyfrowanie, RASP, przepisy dotyczące przechowywania danych itp. W połączeniu z rozwiązaniami RASP, takimi jak AppSealing, staje się potężnym antidotum na dzisiejsze problemy związane z bezpieczeństwem.