Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
„Niewidzialny” backdoor w JavaScript – zobacz Proof of Concept
Kilka dni temu opisywaliśmy wykorzystanie algorytmu Bidi do ukrywania złośliwej zawartości w kodach źródłowych. Dziś natomiast zapoznamy się z tym opisem, który bardzo dobrze tłumaczy sposób dodania niewidocznego backdooru do kodu JavaScript. Wykorzystywany jest rzeczywisty niewidzialny znak (taki jak tutaj) w kodowaniu Unicode. Kod wygląda następująco:
To typowy health check, który polega na wykonaniu komend ping i curl odpowiednio do Google.com i Example.com, po czym zwróceniu konkretnego statusu. Badacze zastosowali znak „ㅤ”, który nosi nazwę Hangul Filler.
Jak dowiadujemy się z opisu, wszystkie znaki Unicode z właściwością ID_Start mogą być użyte w roli identyfikatorów. W JavaScript identyfikatory (czyli po prostu tekst oznaczający funkcję, zmienną czy właściwość) mogą zawierać litery i cyfry, jak również znaki $ i _. Wielkość liter także ma znaczenie.
Wspomniany znak zawiera właściwość ID_Start, więc może zostać użyty w nazwie zmiennej. Aby dodać go do kodu, należy zastosować escape sequence. Polega to na zastąpieniu wybranego znaku ciągiem \u i dodaniu jego kodu heksadecymalnego. W powyższym kodzie użyto „niewidzialnego” znaku we fragmentach:
const { timeout,\u3164} = req.query;
i
const checkCommands = [
'ping -c 1 google.com’,
'curl -s http://example.com/’,\u3164
];
Dzięki tej sztuczce req.query będzie zawierał nie tylko parametr timeout, ale również parametr „ㅤ”. Z kolei tablica checkCommands będzie posiadała zmienną „ㅤ”.
W przykładzie badaczy użyto funkcji exec mogącej wykonywać polecenia w systemie operacyjnym. Jeśli w jakimkolwiek kodzie JavaScript wykorzystującym funkcję exec zostanie dodany Hangul Filler, wystarczy przejść pod adres endpointa, dodając ?%E3%85%A4=<polecenie>. Na poniższym zrzucie ekranu widać, że utworzyliśmy katalog sekurak poprzez parametr, którego wartość to mkdir sekurak:
Niestety – nasze działania są nieco ograniczone, tzn. polecenia faktycznie są wykonywane, ale nie dostajemy outputu, więc może być problem z odczytaniem różnych plików.
Sam atak jest ciekawy, bo wykorzystuje właściwości standardów, na które nie mamy większego wpływu. Zawsze należy sprawdzać kod i dbać o odpowiednie zabezpieczenie dostępu do niego. Na razie tylko Vim czy Nano potrafią „rozpoznać” ten „niewidzialny” znak.
–Michał Giza
„Na razie tylko Vim czy Nano potrafią „rozpoznać” ten „niewidzialny” znak.”
Kwrite też widzi ten znak.
Myślę, że większość edytorów, przynajmniej tych systemowych, działających w Linuxie nie ma z tym problemu.
„Jeśli w jakimkolwiek kodzie JavaScript wykorzystującym funkcję exec zostanie dodany Hangul Filler, wystarczy przejść pod adres endpointa, dodając ?%E3%85%A4=.”
Rozumiem, że to dotyczy konkretnego przypadku aplikacji na screenshocie, a nie jest to globalny problem aplikacji Node’owych :)
Programistą Node.js zdecydowanie nie jestem, ale problem jest jeśli w kodzie jest ta funkcja i ktoś doda Hangul Filler. Wtedy znając adres endpoint’a można to wykorzystać. :)
Aplikacja ze screenshota to po prostu uruchomiony kod z pierwszej grafiki, wystarczy doinstalować Express.js poprzez npm.