Polecam wam poniższy filmik znanego youtubera Serpentza, który mieszkał lata w Chinach, stworzył masę filmów o tym, o tym co dzieje się tak naprawdę w Chinach.
Tym razem opowiada o tym, jak chińskie firmy, takie jak m.in. Huawei wykradają zachodnie technologie z błogosławieństwem chińskiego rządu.
Sam kilka lat temu miałem „przyjemność” zorientować się, że jeden z moich produktów został bezczelnie skopiowany i sprzedawany przez chińskiego sprzedawcę pod zupełnie inną nazwą, wiec z cała stanowczością i własnego doświadczenia mogę powiedzieć, że takie rzeczy dzieją się naprawdę i wcale nie trzeba być wielką firmą, żeby paść ofiarą kradzieży własności intelektualnej przez chińskie firmy.
No i stało się. Ktoś w końcu opublikował dewirtualizer dla popularnego systemu zabezpieczającego VMprotect, obsługujący jego najnowsze wersje z pełnymi kodami źródłowymi.
I've decided to publish my VMProtect devirtualizer working for every 3.x version up to the latest 3.6 along with the experimental x64 compiler.
It can be found at https://t.co/zJQHjFG46e licensed under GPL-3, hopefully it attracts some interest in the VTIL project, enjoy 🙂
Wraz z jego publikacją pojawiły się powiązane narzędzia do zrzucania pamięci i naprawy importów aplikacji zabezpieczonych VMprotectem:
I recently found out I really like to break software protectors. So, here's a mini-project I've been working on for the last week or so: VMPDump, an open-source, well-documented VMProtect dumper and import fixer. No more broken dumps! https://t.co/0Zny9aZjmR
Wszyscy, którzy polegali jedynie na wirtualizacji kodu chyba muszą się poważnie zastanowić nad bezpieczeństwem swoich aplikacji.
Być może to dobra pora przerzucić się na inny system zabezpieczający aplikacje ze znacznie bardziej bogatym wachlarzem zabezpieczeń i SDK, do którego jeszcze nikomu nie udało się zrobić unpakera 🙂
Podczas ostatniej sesji pentestów u klienta odkryłem na serwerze skrypt pozostawiony przez dewelopera, który projektował system lata temu.
Skrypt, publicznie dostępny (jego adres był wysyłany do klientów), był wykorzystywany przez jeden z komponentów do zapisywania logów na serwerze, w bardzo oryginalny sposób.
Nie wiem nawet jak to skomentować, po prostu wam pokażę kod:
No więc co się tutaj dzieje? Ten skrypt po prostu pobiera parametry z zapytania POST lub GET i wykorzystuje ich treść do nadpisania istniejącego lub stworzenia nowego pliku na serwerze w podkatalogu „xxx”.
Problem polega na tym, że nie jest przeprowadzona żadna walidacja i możliwe jest stworzenie dowolnego pliku w dowolnym katalogu systemu, także skryptów PHP.
Jak wykorzystać tę lukę?
Kreatywnie. To na pewno. I tak żeby klient zrozumiał, że to nie są żarty. Należy w tym celu skonstruować zapytanie POST do serwera i odpowiednio ustawić parametry:
„xvar” – w tym parametrze zapiszemy nazwę nowo utworzonego skryptu PHP
„yvar” – będzie zawierać treść kodu PHP z tagiem otwierający skrypt <?php i tagiem na końcu, który będzie otwierał wielolinijkowy komentarz PHP „/*”, ponieważ po tej zmiennej zapisywana jest data i zepsułoby to strukturę kodu PHP
„zvar” – tym parametrem zamkniemy wielolinijkowy komenarz PHP „*/* oraz domkniemy tagi skryptu PHP „?>”
Pobieranie zawartości całej strony
Poniższy skrypt został tak zapisany, że wykorzystując rozszerzenie ZIP dla PHP tworzy archiwum (bez kompresji, żeby nie wydłużać czasu działania skryptu) ze wszystkimi plikami znajdującymi się na stronie.
Do stworzenia tego skryptu na serwerze wykorzystując znalezioną podatność wykorzystałem rozszerzenie dla Chrome – RestMan. Po ustawieniu rodzaju zapytania (POST) i parametrów, wadliwy skrypt zwrócił „1” co jak widać świadczy o tym, że wykonał się do końca.
Teraz wystarczy wpisać w przeglądarkę adres witryny i nazwę skryptu, znajduje się on w katalogu „xxx/dump.php” i jeśli wszystko pójdzie ok, stworzy „piętro wyżej” archiwum ZIP z całą zawartością strony.
Problem może być czas potrzeby do działania skryptu PHP, ograniczony ustawieniami w pliku konfiguracyjnym php.ini. Można go sobie wydłużyć wykonując funkcję PHP set_time_limit(10 * 60); zaraz na początku skryptu.
Zdalna powłoka
Z ciekawszych rzeczy, które można podrzucić jest zdalna powłoka, którą można wykorzystać do zdalnego wykonywania poleceń, dzięki funkcji system() wbudowanej w PHP:
Funkcja ta może być i często jest wyłączona w konfiguracji PHP, ale warto o tym wiedzieć.
Czy to w ogóle błąd?
Zastanawiałem się nad tym chwilę, bo adres skryptu był wysyłany do klientów systemu po określonej akcji i nie mogli mieć świadomości, co się dzieje po jego wykonaniu tzn. że w podkatalogu „xxx” tworzone są nowe pliki. Bo skąd?
Jednak dalsze testy tego archaicznego systemu pozwoliły odnaleźć innego kwiatka, który tego wyżej bije na głowę:
<?php
// downloading a file
$filename = $_GET['filename'];
// fix for IE catching or PHP bug issue
header("Pragma: public");
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
// browser must download file from server instead of cache
// force download dialog
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
// use the Content-Disposition header to supply a recommended filename and
// force the browser to display the save dialog.
header("Content-Disposition: attachment; filename=".basename($filename).";");
/*
The Content-transfer-encoding header should be binary, since the file will be read
directly from the disk and the raw bytes passed to the downloading computer.
The Content-length header is useful to set for downloads. The browser will be able to
show a progress meter as a file downloads. The content-lenght can be determines by
filesize function returns the size of a file.
*/
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
@readfile($filename);
exit(0);
?>
To raczej trudno pobić.
Skrypt pozwala pobrać dowolny plik z serwera, wystarczy np. ustawić parametr „filename” na „index.php” lub jakiś inny, często używany plik jak „config.php”, żeby dobrać się do reszty systemu.
Klient zaskoczony
Po wskazaniu błędów i zaprezentowaniu możliwości klient był zaskoczony, że takie coś w ogóle było możliwe, jednak wynikało to z wieku systemu i metod tworzenia oprogramowania wykorzystywanych lata temu, których już raczej nie doświadczymy. Chociaż, kto wie ile jeszcze takich starych kwiatków wisi na produkcji 🙂
Przez ostatni tydzień pisałem rozszerzenie dla darmowego środowiska programistycznego Visual Studio Code, które pozwala na bezpośrednie szyfrowanie stringów i plików w edytorze IDE wykorzystując mój projekt StringEncrypt.
Rozszerzenie pozwala w prosty sposób wstawiać zaszyfrowane ciągi tekstowe lub zaszyfrowaną zawartość wybranego pliku (czy to tekstowego, czy binarnego) w edytorze środowiska programowania.
Nie trzeba ręcznie szyfrować stringów wykorzystując jakieś proste xorowanie, albo męczyć się z importowaniem różnych dziwnych bibliotek kryptograficznych (i modlić się, żeby się wszystko poprawnie skompilowało), żeby zaszyfrować mały string lub jakiś plik.
1. Wstawianie nowego zaszyfrowanego tekstu
Wystarczy otworzyć menu kontekstowe
Wybrać Insert Encrypted String
Wpisać label dla zaszyfrowanego stringa
Wpisać zawartość stringa
Wstawianie zaszyfrowanego tekstu
2. Szyfrowanie zaznaczonego tekstu
Należy zaznaczyć dowolny tekst
Z menu kontekstowego wybrać Encrypt Selected Text
Wpisać label dla zaszyfrowanego string
Szyfrowanie zaznaczonego tekstu
3. Wstawianie zaszyfrowanego pliku
Z menu kontekstowego należy wybrać Insert Encrypted File
Należy wskazać plik do zaszyfrowania (4 MB max.)
Wpisać label dla zaszyfrowanego pliku
Wstawianie zaszyfrowanego pliku
Jak to działa?
Całość opiera się na polimorficznym silniku projektu StringEncrypt, generującym każdorazowo losowy kod deszyfrujący w wybranym języku programowania (których jest całkiem sporo).
Jak zainstalować?
Rozszerzenie można zainstalować bezpośrednio z marketu Visual Studio Code: