18.11.2014 Views

JIT SPRAY АНАЛИЗ TDSS - Xakep Online

JIT SPRAY АНАЛИЗ TDSS - Xakep Online

JIT SPRAY АНАЛИЗ TDSS - Xakep Online

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

ВЗЛОМ<br />

0xXXYY0104 — начала <strong>JIT</strong>-шеллкода<br />

Память «RWX» c <strong>JIT</strong>-кодом<br />

до начала кода с XOR всегда постоянное. Дабы избежать нулевых<br />

байт в адресе ищем первый аргумент, в младших разрядах адреса<br />

не будет нулевых байтов, и первый такой адрес оказался 0x0104<br />

со значением десятого аргумента для XOR. В итоге окончательный<br />

указатель будет 0xXXYY0104, где XXYY могут быть любым значением<br />

из центральной части карты памяти, например 0x0607 или 0x0808 и<br />

т.д. Таким образом, ASLR побежден.<br />

ÈÍÚÅÊÖÈß ÊÎÄÀ<br />

Допустим, мы передали управление по адресу 0x07070104, там<br />

у нас значение 10-го аргумента из XOR-строки. Предположим,<br />

десятый параметр для XOR равен 0x01020304, а одиннадцатый —<br />

0x1a1b1c1d, тогда по адресу 0x07070104 будет следующий код:<br />

. . .<br />

07070104 0403 ADD AL, 3 ; 10-å çíà÷åíèå<br />

07070106 0201 ADD AL, [ECX] ; âòîðàÿ ÷àñòü<br />

-- âûðåçàíî 12 áàéò –<br />

0707011A 81F01D1C1B1A XOR EAX, 1A1B1C1D ; 11 çíà÷åíèå<br />

ñ XOR<br />

. . .<br />

Так как у нас LITTLE-ENDIAN система, то процессор берет значения<br />

«задом наперед», и вместо 0x0304 мы можем написать любые<br />

команды в оп-кодах. А вот 0x0201 мы должны заменить строго на<br />

14EB (EB14 = JMP +0x14), чтобы передать управление на одиннадцатый<br />

параметр. Когда мы говорили про Flash, было легче,<br />

так как там параметры шли один за другим, тут же у нас разрыв<br />

в 20 (0x14) байт, поэтому последние два байта надо «тратить» на<br />

переход между параметрами. К примеру, десятый и одиннадцатый<br />

параметр:<br />

..^0x14EB9090^0x14EBCC90^..<br />

Будут скомпилированы в:<br />

. . .<br />

07070104 90 NOP<br />

07070105 90 NOP<br />

07070106 EB14 JMP 0707011C<br />

-- âûðåçàíî 14 áàéò –<br />

0707011C 90<br />

NOP<br />

0707011D CC<br />

INT3<br />

0707011E EB14<br />

JMP …<br />

. . .<br />

У нас получилась связь между параметрами и выполнение кода,<br />

сначала пустые операторы, а затем прерывание. Итак, DEP мы тоже<br />

обошли...<br />

072<br />

<strong>JIT</strong>-ØÅËËÊÎÄ<br />

Теперь нам надо написать связанный шеллкод, который мы будем<br />

внедрять в память с помощью XOR в JavaScript. Дело кажется<br />

очень трудным, так как у нас есть всего два байта на команду. В<br />

Flash мы могли использовать и трех- и пятибайтные команды,<br />

но тут у нас жесткое ограничение. Кажется, что дело — труба, но<br />

вспомним еще одно важное отличие между <strong>JIT</strong> <strong>SPRAY</strong> в Flash и<br />

Safari — права на память. В Flash они были «R-X» (чтение и исполнение),<br />

а вот в Safari — «RWX», то есть мы можем еще и писать<br />

в память. Никогда не оставляй исполняемую память доступной на<br />

запись, ибо этот, казалось бы, маленький недочет делает возможным<br />

внедрение шеллкода. Поясню: мы заполнили память RWXблоками<br />

и, допустим, передали управление на <strong>JIT</strong>-блок 07070000.<br />

Там у нас будет связанный шеллкод с командами по два байта.<br />

Двух байт вполне достаточно для операции копирования — MOV<br />

[ECX], EAX (0x8901 в оп-кодах). Если ECX будет указывать на следующую<br />

страницу — 0x07080000, а в EAX будут содержаться первые<br />

четыре байта от шеллкода из метасплойта, то произойдет копирование<br />

шеллкода в RWX-память (W позволит нам делать это). Когда<br />

таким образом мы скопируем весь метасплойт-шеллкод кусками по<br />

четыре байта через регистр EAX, по адресу 0x0708000 будет лежать<br />

боевой шеллкод, причем в исполняемой памяти. Далее делаем<br />

JMP ECX (0xFFE1 — также два байта) на эту память, и код оттуда<br />

исполнится без лишних вопросов.<br />

ÄÂÀ ÁÀÉÒÀ ÁÎËÈ<br />

Мы умеем копировать и передавать управление с помощью<br />

регистров. Двух байт для этого достаточно, но прежде всего надо<br />

научиться с помощью этих двух байт заносить произвольные значения<br />

в регистры. MOV REG, VALUE занимает 5 байт. С помощью<br />

двух байт мы можем заносить значения только в младшие разряды<br />

регистра. Для этого будем использовать MOV AL, 01 (0xB001) и MOV<br />

AH, 02 (0xB402), так мы занесли в младшие разряды EAX 0x0201, и<br />

регистр в общем содержит 0xXXYY0201. Как же можно занести значение<br />

в старшие разряды? Первое, что мне пришло в голову — это<br />

побитовый сдвиг влево — SHL EAX, 1 (0xD1E0). Если мы хотим занести<br />

в регистр ECX-адрес блока, куда хотим копировать шеллкод,<br />

то заносим сначала в младшие регистры значение старших, потом<br />

делаем шестнадцать операций сдвига влево... и в итоге значения<br />

младших разрядов сдвигаются на место старших. Потом заносим<br />

еще раз уже значения младших разрядов. План хорош, да оказалось,<br />

что не очень — дело в том, что шеллкод получается очень<br />

большой, и из-за этого долго компилируется <strong>JIT</strong>-компилятором,<br />

но это не главное. Хуже всего то, что размер блока с компилированным<br />

кодом становится больше 0x10000 байт, а это значит, что<br />

блоки идут друг от друга с двойным разрывом: адрес блока N есть<br />

0x06060000, тогда адрес блока N+1 будет 0x06080000 (а должно<br />

быть 0x06070000). Таким образом, работоспособность <strong>JIT</strong> <strong>SPRAY</strong><br />

зависит от четности третьего разряда. Короче говоря, стабильность<br />

работы — 50%. Очевидно, что проблема в шестнадцати операциях<br />

XÀÊÅÐ 09 /140/ 10

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!