8(495)909-90-01
8(964)644-46-00
pro@sio.su
Главная
Системы видеонаблюдения
Охранная сигнализация
Пожарная сигнализация
Система пожаротушения
Система контроля удаленного доступа
Оповещение и эвакуация
Контроль периметра
Система домофонии
Парковочные системы
Проектирование слаботочных сетей
Аварийный
контроль
Раздел: Документация

0 ... 37 38 39 40 41 42 43 ... 102

Листинг 4.5. Дизассемблерный листинг переполняющейся программы с краткими комментариями

.text:00401000 mainproc near: CODE XREF: start+AFvp

.text:00401000

.text:00401000 var 14- dword ptr -14h : this

.text:00401000 var 10- dword ptr -lOh : *a

.text:00401000 var C= byte ptr -OCh

.text:00401000 var 4- dword ptr -4 .text:00401000

.text:00401000push ebp

.text:00401001mov ebp. esp

здесь непригодно и приходится уповать на индексное, все еще остающееся т. ретической экзотикой, робко осваивающей окружающий мир.

Модифицировать указатель на объект и/или указатель на виртуальную табли. цу намного проще, поскольку они не только находятся в области памяти, д0. ступной для модификации, но зачастую располагаются в непосредственной близости от переполняющихся буферов.

Модификация указателя this приводит к подмене виртуальных функции объек-та. Достаточно лишь найти в памяти указатель на интересующую нас функцию (или вручную сформировать его в переполняющемся буфере) и установить На него this с таким расчетом, чтобы адрес следующей вызываемой виртуальной функции попал на подложный указатель. С инженерной точки зрения это до-статочно сложная операция, поскольку, кроме виртуальных функций, объекты еще содержат и переменные, которые более или менее активно используют Переустановка указателя this искажает их «содержимое», и очень может быть, что уязвимая программа рухнет раньше, чем успеет вызвать подложную виртуальную функцию. Можно, конечно, сымитировать весь объект целиком, но не факт, что это удастся. Сказанное относится и к указателю на объект, поскольку с точки зрения компилятора они скорее похожи, чем различны. Однако наличие двух различных сущностей дает атакующему свободу выбора — в некоторых случаях предпочтительнее затирать указатель this, в некоторых случаях -указатель на объект (листинги 4.4 и 4.5).

Листинг 4.4. Фрагмент программы, подверженной последовательному переполнению при записи, с затиранием указателя на таблицу виртуальных функций

class А{ public:

virtual void f() { printfClegaHn"):};

}:

cnainO {

char buff[8]: A *a = new A: printf("passwd:"):gets(buff):

a->f():


ФИ

,.BlB03subesp. I4h

"01003: онрываем кадр сгека и резервируем 14П стековой памяти

. 0Q401003:

•«ЦОМСбPush4

00401008сoperator new(uint)

??/n!nnn• выделяем память для нозого экземпляра объекта А и получаем указатель

text text text text text .text text text text text text .text text text

0040100D 0040100D

0040]C10mov [ebp-wariO] eax

С0401010: записываем указатель на обьект в переменную var lD

00401010:

00401013сто [ebp+var 10]. О

00401017J short 1ос 401026

00401017: проверка успешности выделения памяти 00401017

00401019mov есх. Lebp+var 10]

0О4О101Сcall А:: А

00401С1С: вызываем конструктор объекта А 0040101С

00401021nov £oDp-var 14J. eax

00401021: заносим воззоаденный указатель this в переменную var 14

С0401021:

lext 004C102Dloc 40102D: : CODE XREF: main+24Aj

;ext.00401023mov eax. [ebp*var 14J

text:00401C30mov [ebp+var /.]. eax

•cxt:00401030: берем указатель th>s и перепрятываем ею в переменную var 4

• »t:00401030.

СС0401033pusn offset aPasswd "passwd:"

>::00401038call prir.tf

::0040103Dadd esp. 4

"*-:0040103D. выводим приглашение к вводу на зкран

:.004C103D;

»t:OC401040lea есх. [ebp+var C]

-:00401040; переполняющийся буфер расположен ниже указателя на объект и

Л-0040104С; перзи-тного указателя this, но выше порожденного указателя this.

t:00401040: что делает последний уязвимым

itxt:0040I040;

text:004C!043 push есх

lext:00401044са11 gt?;s

№«00401049add esp. 4

ext:00401049: чтение строки в буфер

tn«:00401049;

t:0040104Cmov edx. [ebp+var 4]

t 00401C4C; за-рукаеч уязвимый указатель this в регистр EDX

t:00401C4C•

J21Mfmov oax. [edx]

°0401()4F 13БЛеК)е1 адреС виРт>альн0Й таблиЧы

-t-од401051mov еСХ [ebp"var-4]

401051; передаем функции указатель this

* "6Продолжение >


ИНДЕКСЫ

Индексы являются своеобразной разновидностью указателей. Грубо гоВ0,ц относительные указатели, адресуемые относительно некоторой базы. ~st • те, p[i] можно представить и как *(p+i), практически полностью уравн и i в правах.

Модификация индексов имеет свои слабые и сильные стороны, "fqi указатели требуют задания абсолютного адреса целевой ячейки, который неизвестен, в то время как относительный вычисляется «на ура». ИндскС1 до нящисся в переменных типа char, лишены проблемы нулевых символ" , дексы, хранящиеся в неременных типа int, могут беспрепятственно 3 ячейки, расположенные «выше» стартового адреса (то есть лежаШне в

Листинг 4.5 (продолжение)

.text:00401051

.text:00401054call dwo>TJ Dtr [eax]

.text:00401G54 : вызываем виртуальную функцию -первую функцию виртуальной таблиц .text:00401C54 :

.text:00401056mov esp. ebp

.text:00401058pop ebp

.text .-00401059retn

.text:00401059 mainendp

Рассмотрим ситуацию, когда следом за переполняющимся буфером идет ука затель на скалярную переменную р и сама переменная х, которая в некоторь-, момент выполнения программы по данному указателю и записывается (п0ря док чередования двух последних переменных не существенен, главное, чтобн переполняющийся буфер затирал их все). Допустим также, что с момента переполнения ни указатель, ни переменная не претерпевают никаких измененщ (или изменяются предсказуемым образом). Тогда, в зависимости от состояния ячеек, затирающих оригинальное содержимое переменных х и р, мы сможем записать любое значение х по произвольному адресу р, осуществляя это «рука ми» уязвимой программы. Другими словами, мы получаем аналог функций Р(К и PatchByte/PatchWord языков Бейсик и ГОА-Си соответственно. Вообще-то ш выбор аргументов могут быть наложены некоторые ограничения (например функция gets не допускает символа нуля в середине строки), но это не слип: ком жесткое условие, и имеющихся возможностей вполне достаточно для захвата управления над атакуемой системой (листинг 4.6).

Листинг 4.6. Фрагмент программы, подверженной последовательному переполнению при записи, с затиранием скалярной переменной и указателя на данные, поглощающие затертую переменную

cata ptr() {

char beff[8]: int x; int *p: printf("passws:"): Qets(buff):

*p = x;



0 ... 37 38 39 40 41 42 43 ... 102