Написал программу, которая переполняет буфер в самой себе. Код (Text): #define OVERFLOW_LEN 72 #define BUFFER_LEN 64 char overflow[] = "\x68\x22\x12\x40\x00" // push 00401222h - старый адрес main module (куда ret из main) "\xc3" // retn "\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\x90\x90\x90\x90\x90\x90\x90"\ "\x90\x90\x90\x90\x90\x90\x90\x90"\ "\x90\x90\x90\x90\x90\x90\x90\x90"\ "\xc0\xff\x12\x00" "\x34\xff\x12\x00"; int i; int main(int argc, char* argv[]) { char arr[BUFFER_LEN]; for(i=0; i < OVERFLOW_LEN; i++) { arr[i]=overflow[i]; } return 0; }; Для тех,кто захочет сконпелить - адреса рассчитаны для lcc32. Если я правильно понял суть DEP, она должна вылетать, т.к. мы выполняем код из стека. Но она этого не делает. ЧЯДНТ? Кто уверен, что у него включен DEP - проверьте плиз у себя.
Вы какой DEP имеете ввиду программный или аппаратный. Да и по умолчанию деп включен только для критический файлов в системе типа Explorer.exe и.т.д. Если хотите увидеть включен деп или нет в вашей программе для начало проверьте с помощью процесс эксплорера а потом тестируйте.
У меня вообще 2к, я на чужих машинах проверял. А как процесс эксплорером проверить? Может, кто-то у себя проверит?
>>Может, кто-то у себя проверит? Приведенный пример жизнеспособен только совсем в тепличных условиях. Надо ориентироваться хотя бы на наличие софтварного деп. >>DEP только на х64 работает или мне показалось? На 64 всегда включен аппаратный DEP для 64-битных приложений, для 32-битных в 64-битной ОС можно настраивать. На 32 тоже работает. Но это не проблема, по обходу hardware-enforced DEP была давно статья в Uninformed-е, посмотрите на http://uninformed.org/
Так его кто-то на компе с гарантированно работающим DEP запускал? Оно валится или нет? Ты про это http://www.securitylab.ru/analytics/263899.php? А как обходить софтверный DEP?
Windows XP SP2 x64 Edition Unhandled exception at 0x0012ff34 in buffer-overflow03.exe: 0xC0000005: Access violation.
2ololoe: А где в вашем примере, собственно, выполнение кода из стека? - в вашем коде есть переполнение буфера стека... Вот если бы вы переписали код функции в буфер arr, а затем выполнили бы эту функцию, например так: typedef void( *TpFunc)(void); TpFunc pFunc = (TpFunc)arr; pFunc(); то это можно назвать выполнение кода функции на стеке!
gorodon, "\x34\xff\x12\x00"; - это адрес начала массива в стеке, им перезаписывается старый eip. Насчет ptr кстати идея, можно это переписать так, чтобы адреса не были рассчитаны под конкретный конпелятор?
Насколько я понимаю, суть DEP - запретить выполнение кода на страницах памяти процесса, не имеющих флага PAGE_EXECUTE. При вкюченном DEP происходит генерация исключения. Если вы именно этот факт хотите зафиксировать, то надо написать простую програму выполнения кода функции на стеке - как я писал выше. Тогда при включенном DEP будет генерится исключение, при выключеном DEP - функция будет работать. Другой вопрос - если вы хотите отрабатывать прехват управления методом переполнения буфера... Где-то у Криса Касперски я видел статьи по этому поводу...там описано, кстати, как обойти DEP, вызвав VirtualProtect и изменив тем самым атрибуты страниц памяти. >Насчет ptr кстати идея, можно это переписать так, чтобы адреса не были рассчитаны под конкретный конпелятор? ? Для этого надо заранее знать значение указателя стека - ну, для тренирвки можно, конечно - перед заполнением буфера arr вычислить значение указателя стека и поместить его с нужным смещением в overflow...
ololoe Программный DEP на мой взгляд просто добавляет при вызове системных функций проверку куда происходит возврат, и если возврат происходит на страницу для которой запрещено выполнение, то генерируется исключение. То есть код в стеке выполнять можно, но только пока не вызываем системных функций. Хотя вернуться в страницу для которой выполнение разрешено вполне можно.
ololoe, Black_mirror Вот примерчик, демонстрирующий работу DEP - ограничение выполнения кода на стеке: Код (Text): void fSomeFunc(void) { __asm{ push eax mov eax,0x01020304L pop eax } } const char buffunc[] = "\x50\xb8\x04\x03\x02\x01\x58\xc3"; #pragma optimize( "", off ) int main(int argc, char* argv[]) { char arr[32];//,*ptr; typedef void ( *TpFunc)(void); TpFunc pFunc = (TpFunc)(void*)arr; // //Обычная функция fSomeFunc(); // // for(int i=0;i<8;i++) { arr[i] = buffunc[i]; } //Выполняем код функции на стеке printf("Execute code on stack..."); pFunc(); printf("Ok!"); // return 0; } #pragma optimize( "", on ) Если скомпилить эту программку и запустить с выключенным DEP, то программа отработает...без гвоздей. Если программу запустить с включенным DEP, то появится сообщение типа этого: "To elp protect your computer, Windows has closed this program."