#linux #memory #x64 #x86_64 #виртуальная_память
Изучаю как устроена атака на переполнение буфера. Написал вот такую программу typedef void(*Function)(); int main() { const char* shell = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; Function f = (Function)shell; f(); return 0; } shell - пара десятков nop-ов.(0x90 - опкод nop-a). Пошагово прошелся по ней в gdb и она падает от segfault при вызове f, а точнее при выполнении инструкции callq *%rdx При этом в rdx записан адрес 0x4005d8( Именно по этому адресу располагаются nop-ы). И все это можно было бы объяснить тем, что адрес 0x4005d8 относится к странице у которой не выставлено право на исполнение, но: 1) Вот вывод утилиты pmap для этого процесса 26040: ./main 0000000000400000 4K r-x-- main 0000000000600000 4K r---- main 0000000000601000 4K rw--- main 0000000001c65000 132K rw--- [ anon ] 00007f40de3ce000 1792K r-x-- libc-2.23.so 00007f40de58e000 2048K ----- libc-2.23.so 00007f40de78e000 16K r---- libc-2.23.so 00007f40de792000 8K rw--- libc-2.23.so 00007f40de794000 16K rw--- [ anon ] 00007f40de798000 152K r-x-- ld-2.23.so 00007f40de995000 12K rw--- [ anon ] 00007f40de9bd000 4K r---- ld-2.23.so 00007f40de9be000 4K rw--- ld-2.23.so 00007f40de9bf000 4K rw--- [ anon ] 00007ffd8e874000 132K rw--- [ stack ] 00007ffd8e924000 12K r---- [ anon ] 00007ffd8e927000 8K r-x-- [ anon ] ffffffffff600000 4K r-x-- [ anon ] total 4356K И если я правильно понимаю что тут написано, то у диапазона адресов 0х400000-0х60000 есть право на исполнение. 2) Что подтверждает предыдущий пункт: адрес функции main был 0х400507 что довольно близко к последовательности nop-ов. Однако если в rdx положить адрес main то никакого segfault-а не происходит. Проясните, пожалуйста, что не так.
Ответы
Ответ 1
Учитывая, что сегмент константных данных (а именно туда попадает const char* shell) отображается без права на исполнение, скорее всего, вы столкнулись с ASLR. ASLR (Address Space Layout Randomisation, разбиение адресного пространства случайным образом) — это механизм, который как раз и направлен против шелл-атак, полагающихся на фиксированный адрес тех или иных участков памяти. Он разбрасывает программу, библиотеки и стек случайным образом по всей виртуальной памяти, доступной программе, причём из запуска в запуск результат подобного распределения отличается. При первом запуске (под gdb) адрес 0x4005d8 попадал в сегмент неизменяемых данных программы (на это указывают права доступа сегмента, да и const-переменные находятся только там). При втором же запуске (для pmap) по тому адресу стал располагаться сегмент кода. Если вы хотите получить согласованный результат, запускайте pmap параллельно с gdb, в другом окне или вкладке консоли. (Немного о праве на исполнение блока памяти) Начиная с версии 2.3.23, Linux имеет встроенную поддержку DEP. DEP (Data Execution Prevention, предотвращение выполнения данных) — это механизм, направленный на запрет исполнения кода там, где должны лежать данные (к примеру, в стеке или сегменте данных). Он работает за счёт того, что к уже существующим флагам прав доступа к странице (чтение, запись, доступ только из режима ядра и т. д.) был добавлен ещё один (запрет на исполнение), который операционная система устанавливает для всех страниц, не соответствующих сегментам кода исполняемых файлов (а main() как раз и лежит в подобном сегменте). Единственное, где может сработать ваш шелл — это в областях памяти, созданных при помощи mmap() с одновременно выставленными флагами PROT_EXEC и PROT_WRITE.
Комментариев нет:
Отправить комментарий